简体   繁体   中英

Groovy script not parsing XML correctly

I am trying to use Groovy to parse the following XML:

<list>
    <list>
        <widget>
            <fizz id="3" />
            <buzz>false</buzz>
            <explanations/>
        </widget>
        <widget>
            <fizz id="3" />
            <buzz>true</buzz>
            <explanations>
                <string>What is the meaning of life?</string>
                <string>I like the color blue.</string>
            </explanations>
        </widget>
        <widget>
            <fizz id="45" />
            <buzz>true</buzz>
            <explanations>
                <string>I could really go for some pizza right now.</string>
            </explanations>
        </widget>
    </list>
</list>

If a <widget/> element has a true <buzz/> child, then it will start aggregating all explanations/string children into a master List<String> . Thus, given the sample XML above, it would have the following behavior:

  1. First list/list/widget/buzz is false , so don't do anything
  2. Second list/list/widget/buzz is true , so engage string aggregation mode:
    1. The second list/list/widget/explanations has 2 <string/> children; add them both to a master list ( masterList )
  3. Third list/list/widget/buzz is true , so continue aggregating its children strings into the master list
    1. The third list/list/widget/explanations has 1 <string/> child; add it to the master list ( masterList )
  4. The masterList now has 3 strings in it: 2 from the 2nd widget, and 1 from the 3rd widget

So far, here's my best attempt:

boolean buzzesExist = false;
List<String> masterList = new ArrayList<String>();

use(DOMCategory) {
    element.normalize();

    element.'widget'.each { widget ->
        // If widget/buzz is true, then buzzes exist.
        if(widget.'buzz'.text) {
            buzzesExist = true;
        }

        // If buzzes exist, then aggregate all explanation strings into
        // into "masterList".
        if(buzzesExist) {
            for(String exp : widget.'explanations')
                masterList.add(exp);
    }
}

This runs, but causes the masterList to contain all sorts of bizarro DOM stuff in it (too large for me to paste in). Can any Groovy gurus spot where I'm goin awrye? Thanks in advance.

Why not XmlParser?

UPDATE :

list = new XmlParser().parseText xml

widgetWithExplanations = list.breadthFirst()
  .findAll { it.buzz.text() == "true" }

masterList = widgetWithExplanations
  .collect { it.explanations.string*.text() }
  .flatten()

assert masterList == [
    "What is the meaning of life?", 
    "I like the color blue.", 
    "I could really go for some pizza right now."]


emptyExplanations = widgetWithExplanations
    .count { !it.explanations.string }

assert emptyExplanations == 0

Otherwise your domcategory is probably missing exp.text() inside the for loop.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM