Reputation: 56944
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:
list/list/widget/buzz
is false
, so don't do anythinglist/list/widget/buzz
is true
, so engage string aggregation mode:
list/list/widget/explanations
has 2 <string/>
children; add them both to a master list (masterList
)list/list/widget/buzz
is true
, so continue aggregating its children strings into the master list
list/list/widget/explanations
has 1 <string/>
child; add it to the master list (masterList
)masterList
now has 3 strings in it: 2 from the 2nd widget, and 1 from the 3rd widgetSo 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.
Upvotes: 2
Views: 336
Reputation: 14549
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.
Upvotes: 1