You need to enable JavaScript to run this app. groovy.xml.XmlParser解析冒号分隔唯一属性时丢失属性问题
优惠活动
大模型
产品
解决方案
定价
更多

groovy.xml.XmlParser解析冒号分隔唯一属性时丢失属性问题

Groovy XmlParser处理后丢失命名空间声明问题解答

问题结论

首先明确:这不是groovy.xml.XmlParser的bug,属于XML解析器的标准行为。

原因说明

XML解析器默认只会识别元素名、属性名中使用的命名空间前缀,不会主动扫描属性值内部的文本内容判断命名空间是否被使用。你的示例中xs前缀仅出现在xsi:type的属性值xs:int中,XmlParser判定该命名空间未被实际使用,所以序列化时自动移除了未使用的命名空间声明,仅保留了确实用到的xsi命名空间。

解决方案

方案1:手动补全需保留的命名空间

序列化节点前手动给目标节点添加需要保留的命名空间声明即可,修改后的代码如下:

import groovy.xml.XmlParser

class CreateSelectedXML {
    static void xmlHandling(List<String> listCodes, String TEST_FILE_NAME) {
        def docdup = new StringBuilder()
        // 预先定义需要保留的命名空间,避免硬编码重复
        def retainedNamespaces = [
            'xmlns:xs': 'http://www.w3.org/2001/XMLSchema'
        ]
        // 优化:将XML解析放到循环外,仅解析一次即可,大幅提升性能
        File input = new File(TEST_FILE_NAME)
        def doc = new XmlParser().parse(input)

        listCodes.each { code ->
                doc.findAll{it.@code == code[0].toString()}.each {
                    // 手动添加命名空间到当前节点属性
                    it.attributes().putAll(retainedNamespaces)
                    def temp = groovy.xml.XmlUtil.serialize(it).toString()
                    docdup.append(temp)
                }
            }
        }
    }
}

方案2:通用适配场景

如果需要处理大量带xsi:type属性的节点,可以写通用工具方法,遍历所有节点的xsi:type属性,提取属性值中的命名空间前缀,自动补全对应的命名空间声明即可。

额外优化提示

原代码中每次遍历listCodes元素都会重新解析XML文件,当XML文件较大或列表元素较多时性能损耗很高,上面修改后的代码已经将解析逻辑移到循环外,仅需解析一次即可。

内容的提问来源于stack exchange,提问作者Sasori

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.10 01:15:03