Groovy中XmlSlurper实现XML转Map时重复节点分组方法
Groovy实现XML转Map(自动处理重复节点为List
原有XmlSlurper转Map的实现默认会覆盖同层级同名节点的值,无法满足重复节点转列表的需求,可通过同层节点分组判断的逻辑改造递归转换方法,代码可直接运行:
import groovy.xml.XmlSlurper def xmlToMap(node) { // 叶子节点直接返回文本内容 if (node.children().isEmpty()) { return node.text() } Map result = [:] // 同层级子节点按节点名分组 def childNodeGroups = node.children().groupBy { it.name() } childNodeGroups.each { nodeName, nodeList -> if (nodeList.size() == 1) { // 无重名单节点,递归转换 result[nodeName] = xmlToMap(nodeList[0]) } else { // 重名重复节点,转换为Map组成的List result[nodeName] = nodeList.collect { repeatNode -> [(repeatNode.name()): xmlToMap(repeatNode)] } } } // 当前节点所有子节点为同名重复节点时,直接返回列表不额外包一层Map if (childNodeGroups.size() == 1 && childNodeGroups.values().first().size() > 1) { return result.values().first() } return result } // 测试示例(注:原示例XML缺少<body>开标签,已补全为合法XML结构) def demoXml = ''' <body> <head>test</head> <tail> <name>1</name> <name>2</name> </tail> </body> ''' def rootNode = new XmlSlurper().parseText(demoXml) def targetMap = xmlToMap(rootNode) // 输出结果:[head:test, tail:[[name:1], [name:2]]],与预期结构完全匹配 println targetMap
逻辑说明
- 核心规则:遍历每个节点的子节点时先按节点名分组,同组节点数为1时按普通键值对递归存储,节点数≥2时自动转为List结构,每个节点单独包装为Map后存入列表。
- 适配场景:如果重复节点内部还有多层嵌套的重名节点,递归逻辑会自动完成多层转换,无需额外适配。
- 扩展提示:如果需要解析XML节点属性,可在转换逻辑中遍历节点的
attributes()方法,将属性合并到对应层级的Map中即可。
注意:传入的XML必须是结构完整的合法格式,原示例中缺少
<body>根节点的开标签,会导致XML解析失败,实际使用时需要保证XML格式正确。
内容的提问来源于stack exchange,提问作者arash yousefi
相关产品推荐
相关产品推荐

