2012-12-20 7 views
5

मुझे उम्मीद है कि कोई व्यक्ति कुछ स्पष्ट बताएगा कि मैं यहां याद कर रहा हूं। मुझे लगता है कि मैंने इसे सौ बार किया है और आज रात किसी कारण से, इस से आने वाला व्यवहार मुझे लूप के लिए फेंक रहा है।ग्रोवी नोड.depthFirst() नोड्स और स्ट्रिंग्स की एक सूची लौट रहा है?

मैं कुछ एपीएल में सार्वजनिक एपीआई से पढ़ रहा हूं। मैं एक निश्चित नोड ('शरीर' के भीतर सबकुछ) से सभी पाठ निकालना चाहता हूं, जिसमें विभिन्न प्रकार के बाल नोड भी शामिल हैं। सरल उदाहरण:

<xml> 
    <metadata> 
     <article> 
      <body> 
       <sec> 
        <title>A Title</title> 
        <p> 
         This contains 
         <italic>italics</italic> 
         and 
         <xref ref-type="bibr">xref's</xref> 
         . 
        </p> 
       </sec> 
       <sec> 
        <title>Second Title</title> 
       </sec> 
      </body> 
     </article> 
    </metadata> 
</xml> 

तो अंत में मैं वांछित नोड (फिर से, 'शरीर') के भीतर पेड़ पार और सभी पाठ अपनी प्राकृतिक क्रम में निहित निकालना चाहते हैं। काफी सरल है, इसलिए मैं अभी इस छोटे ग्रूवी स्क्रिप्ट लिखने ...

def xmlParser = new XmlParser() 
def xml = xmlParser.parseText(rawXml) 
xml.metadata.article.body[0].depthFirst().each { node -> 
    if(node.children().size() == 1) { 
     println node.text() 
    } 
} 

... जिसके साथ को उड़ाने की आगे बढ़ता है "विधि का कोई हस्ताक्षर नहीं: java.lang.String.children()"। तो मैं खुद से सोच रहा हूं "रुको, क्या? क्या मैं पागल हो रहा हूँ?" Node.depthFirst() केवल नोड की एक सूची वापस करनी चाहिए। मैं थोड़ा 'exampleof' चेक जोड़ता हूं और पर्याप्त रूप से पर्याप्त हूं, मुझे नोड ऑब्जेक्ट्स और स्ट्रिंग ऑब्जेक्ट्स का संयोजन मिल रहा है। विशेष रूप से एक ही पंक्ति पर इकाइयों के भीतर की रेखाएं स्ट्रिंग्स, उर्फ ​​"इसमें शामिल हैं" और "और" के रूप में वापस आती हैं। बाकी सब कुछ एक नोड है (जैसा कि अपेक्षित) है।

मैं इस आसानी से आसानी से काम कर सकता हूं। हालांकि, यह सही व्यवहार की तरह प्रतीत नहीं होता है और मुझे उम्मीद है कि कोई मुझे सही दिशा में इंगित कर सकता है।

+0

जहां तक जैसा कि मैं बता सकता हूं, Node.depthFirst व्यवहार करता था क्योंकि आप ग्रोवी 1.7 में अपेक्षा करेंगे। Groovy 2.0+ में, मैं नोड्स/स्ट्रिंग्स के समान परिणाम देख रहा हूं। – Joseph

उत्तर

7

मुझे पूरा यकीन है कि यह सही व्यवहार है (हालांकि मुझे हमेशा XmlSlurper और XmlParser को खराब एपीआई मिलते हैं)। सभी चीजों को आप वास्तव में एक नोड इंटरफ़ेस आईएमओ को कार्यान्वित कर सकते हैं और संभावित रूप से TEXT है जिसका उपयोग आप उनसे टेक्स्ट प्राप्त करने के लिए जान सकते हैं।

उन टेक्स्ट नोड्स वैध नोड्स हैं जो कई मामलों में आप हिट करना चाहते हैं क्योंकि यह एक्सएमएल के माध्यम से पहली बार गहराई से चल रहा है। अगर वे वापस नहीं लौटे, तो आपके एल्गोरिदम जांचने के लिए कि क्या बच्चों का आकार 1 काम नहीं करेगा क्योंकि कुछ नोड्स (जैसे <p> टैग) में मिश्रित पाठ और तत्व दोनों हैं।

इसके अलावा, क्यों depthFirst लगातार सभी टेक्स्ट नोड्स को वापस नहीं करता है जहां पाठ एकमात्र बच्चा है, जैसे italic ऊपर, चीजों को और भी बदतर बना देता है।

def rawXml = """<xml> 
    <metadata> 
     <article> 
      <body> 
       <sec> 
        <title>A Title</title> 
        <p> 
         This contains 
         <italic>italics</italic> 
         and 
         <xref ref-type="bibr">xref's</xref> 
         . 
        </p> 
       </sec> 
       <sec> 
        <title>Second Title</title> 
       </sec> 
      </body> 
     </article> 
    </metadata> 
</xml>""" 

def processNode(String nodeText) { 
    return nodeText 
} 

def processNode(Object node) { 
    if(node.children().size() == 1) { 
     return node.text() 
    } 
} 

def xmlParser = new XmlParser() 
def xml = xmlParser.parseText(rawXml) 
def xmlText = xml.metadata.article.body[0].'**'.findResults { node -> 
    processNode(node) 
} 

println xmlText.join(" ") 

प्रिंटों

:

मैं जो (बल्कि instanceof की तरह कुछ का उपयोग करने से) प्रत्येक नोड को संभालने के लिए सही तरीके से इस तरह है क्रम आंकड़ा बाहर जाने के लिए ग्रूवी तरीकों में से हस्ताक्षर का उपयोग करना चाहते के लिए करते हैं

A Title This contains italics and xref's . Second Title 

वैकल्पिक रूप से, XmlSlurper वर्ग शायद और अधिक आप क्या चाहते हैं/यह करने की उम्मीद करता है और text() विधि से उत्पादन का एक और अधिक उचित सेट है। क्या तुम सच में परिणाम के साथ चलने के लिए (क्या XmlParser के लिए "बेहतर" है) डोम किसी भी प्रकार का क्या करने की जरूरत नहीं है, तो मैं XmlSlurper सुझाव देंगे:

def xmlParser = new XmlSlurper() 
def xml = xmlParser.parseText(rawXml) 
def bodyText = xml.metadata.article.body[0].text() 
println bodyText 

प्रिंटों:

A Title 
        This contains 
        italics 
        and 
        xref's 
        . 
       Second Title 
+0

अंतिम टिड्बिट मैं वास्तव में चाहता हूं और वास्तव में जो मैं उम्मीद कर रहा था।मैं शपथ ले सकता था कि मैंने कोशिश की, लेकिन मैंने हर समय गहराई से पहले() वहां छोड़ा होगा जो मुझे एक लूप के लिए फेंक रहा था। – James

+0

ओह, वह और तथ्य यह है कि GPathResult.text() Node.text() से बहुत अलग व्यवहार करता है। मेरी इच्छा है कि दस्तावेज़ थोड़ी अधिक जानकारीपूर्ण हों ... – James

+0

क्या आप कृपया डबल "*" –

संबंधित मुद्दे