创建一个带有循环列表的地图 XML
Create a Map with Lists looping XML
我有一个我无法解决的需求。
我的 XML 如下所示
<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>
我的要求是创建一个包含所有 value2 的地图。
输出应如下所示
[机管局:[123,999]]
[AB:[456,888]]
我无法解决这个问题,需要帮助或指点please.I将需要检查 value1 字段在下一次迭代到下一个节点和存储中是否不同。
请帮忙。
代码可能如下所示:
import groovy.xml.*
def s = '''
<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 XmlParser().parseText(s)
def result = xml.'*'.inject( [:].withDefault{ [] } ){ res, node ->
res[ node.value1.text() ] << node.value2.text()
res
}
assert result == [AA:['123', '999'], AB:['456', '888']]
@injecteer 说的。
另一种方法涉及两个步骤,但可能更容易理解:
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
执行时打印:
─➤ groovy solution.groovy
[AA:[123, 999], AB:[456, 888]]
其中第一个 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
操作从节点中拉出 value2
,留下 result
变量作为 Map<String, List<String>>
。
<<编辑>>
我意识到这个解决方案实际上使用了一个非常奇怪的 groovy “功能”,如果您调用 list.someProperty
并且 someProperty
不存在于列表 class 中(例如java.util.ArrayList
), groovy 将 return 一个包含列表元素中所有 someProperty
值的列表。
如果我们想改变这个不使用我们可以做的怪事:
def result = xml.'*'.groupBy {
it.value1
}.collectEntries { k, v ->
[k, v*.value2]
}
instead 它使用 the groovy spread operator 而不是未记录的怪异。
def xml = new XmlSlurper().parseText(data)
def result = xml.'*'.groupBy {
it.value1
}.collectEntries { k, v ->
[k, v.value2]
}
这绝对有效。
我有一个我无法解决的需求。
我的 XML 如下所示
<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>
我的要求是创建一个包含所有 value2 的地图。
输出应如下所示 [机管局:[123,999]] [AB:[456,888]]
我无法解决这个问题,需要帮助或指点please.I将需要检查 value1 字段在下一次迭代到下一个节点和存储中是否不同。
请帮忙。
代码可能如下所示:
import groovy.xml.*
def s = '''
<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 XmlParser().parseText(s)
def result = xml.'*'.inject( [:].withDefault{ [] } ){ res, node ->
res[ node.value1.text() ] << node.value2.text()
res
}
assert result == [AA:['123', '999'], AB:['456', '888']]
@injecteer 说的。
另一种方法涉及两个步骤,但可能更容易理解:
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
执行时打印:
─➤ groovy solution.groovy
[AA:[123, 999], AB:[456, 888]]
其中第一个 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
操作从节点中拉出 value2
,留下 result
变量作为 Map<String, List<String>>
。
<<编辑>>
我意识到这个解决方案实际上使用了一个非常奇怪的 groovy “功能”,如果您调用 list.someProperty
并且 someProperty
不存在于列表 class 中(例如java.util.ArrayList
), groovy 将 return 一个包含列表元素中所有 someProperty
值的列表。
如果我们想改变这个不使用我们可以做的怪事:
def result = xml.'*'.groupBy {
it.value1
}.collectEntries { k, v ->
[k, v*.value2]
}
instead 它使用 the groovy spread operator 而不是未记录的怪异。
def xml = new XmlSlurper().parseText(data)
def result = xml.'*'.groupBy {
it.value1
}.collectEntries { k, v ->
[k, v.value2]
}
这绝对有效。