用于Map分组重复键的Groovy xml

gkl3eglg  于 2022-11-01  发布在  其他
关注(0)|答案(2)|浏览(114)

我有一个xml响应,我想把它转换成一个Map,但是一些xml节点是重复的,所以我想把它们转换成Map列表。目前我正在使用这篇文章中建议的代码:xmlslurper-to-return-all-xml-elements-into-a-map
先谢谢你。
样品:

<head>test</head>
<tail>
    <name>1</name>
    <name>2</name>
</tail>
</body>

我想要下面的Map:

["head" : "test" , "tail" : [["name":"1"],["name":"2"]]]
g9icjywg

g9icjywg1#

问题在于,这段代码:

nodes.children().collectEntries { 
    [it.name(), it.childNodes() ? convertToMap(it) : it.text() ] 
}

覆盖结果Map中的值。我没有设法找到一个优雅的解决方案,而不做一些丑陋的黑客。但这里是我的解决方案:

final xml = """
<body>
<head>test</head>
<test>
<child>Child</child>
</test>
<tail>
<name>1</name>
<name>2</name>
<name>3</name>
<name>4</name>
<name>5</name>
</tail>
</body>
"""

def slurper = new XmlSlurper().parseText(xml)
println convertToMap(slurper)

def convertToMap(nodes) {
    final list = []
    final children = nodes.children().iterator()
    while (children.hasNext()) {
        final child = children.next()
        list << [(child.name()): child.childNodes() ? convertToMap(child) : child.text()]
    }
    final keys = list.collect { it.keySet()[0].toString() }
    if (keys.size() == keys.unique().size()) {
        list.collectEntries { [(it.keySet()[0]): it[it.keySet()[0]]] }
    } else {
        list
    }
}

我在这里所做的是首先收集所有的子元素作为map条目的列表,所以看起来像[[key1:value1], [key2:value2]],然后循环这个中间结构并收集结果。
我希望它能帮助我们向前迈进,也许以后会有人给你一个更好的解决方案,因为正如我所说,目前我还没有找到任何优雅的方法来解决它。

vlurs2pr

vlurs2pr2#

经过一番挣扎,我写了这段代码来解决我的问题,我试图使用MultiValueMap,但它是转换所有的值列表,所以最后我不得不写在我自己:

def xml = new groovy.xml.XmlSlurper().parse(response)
convertToMap(xml)

    def convertToMap(nodes) {
        def map = [:]
        nodes?.children()?.each {
            def key = it.name()
            def value = it.childNodes() ? convertToMap(it) : it.text()
            if (map.containsKey(key)) {
                def currentValue = map.get(key)
                if (currentValue instanceof List) {
                    currentValue.add(value)
                } else {
                    map.put(key, [currentValue, value])
                }
            } else {
                map.put(key, value)
            }
        }
        map
    }

相关问题