I have a requirement which i am not able to solve.
My XML looks like the below
<root>
<node1>
<value1>AA</value1>
<value2>123</value2>
</node1>
<node1>
<node2>
<value1>AA</value1>
<value2>999</value2>
</node2>
<node3>
<value1>AB</value1>
<value2>456</value2>
</node3>
<node4>
<value1>AB</value1>
<value2>888</value2>
</node4>
</root>
My requirement is to create a Map with all the value2's in it.
Output should look like the below [AA:[123,999]] [AB:[456,888]]
i am unable to approach this problem and need help or pointers please.I will need to check if the value1 field is different in the next iteration to the next node and store.
please help here.
What @injecteer said.
Another way involves two steps but might be easier to comprehend:
import groovy.xml.*
def data = '''
<root>
<node1>
<value1>AA</value1>
<value2>123</value2>
</node1>
<node2>
<value1>AA</value1>
<value2>999</value2>
</node2>
<node3>
<value1>AB</value1>
<value2>456</value2>
</node3>
<node4>
<value1>AB</value1>
<value2>888</value2>
</node4>
</root>'''
def xml = new XmlSlurper().parseText(data)
def result = xml.'*'.groupBy {
it.value1
}.collectEntries { k, v ->
[k, v.value2]
}
println result
which, when executed, prints:
āā¤ groovy solution.groovy
[AA:[123, 999], AB:[456, 888]]
where the first groupBy
creates a Map<String, List<xml node>>
where the keys are the AA
, AB
strings and the values are the xml nodes. The second collectEntries
operation pulls out value2
from the nodes leaving the result
variable as a Map<String, List<String>>
.
<< edit >>
I realized this solution actually uses a really weird groovy "feature" where if you call list.someProperty
and someProperty
does not exist on the list class (like java.util.ArrayList
), groovy will return a list with all the someProperty
values from the list elements.
If we want to change this to not use that weirdness we can do:
def result = xml.'*'.groupBy {
it.value1
}.collectEntries { k, v ->
[k, v*.value2]
}
instead which uses the groovy spread operator instead of the undocumented weirdness.