You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用Apache Groovy的XmlSlurper为XML属性添加命名空间?

问题:为XML空元素添加xsi:nil属性

我正在遍历扁平化XML的子元素,需要为空元素添加特定属性。现有代码如下:

import groovy.xml.XmlUtil
import groovy.xml.MarkupBuilder
import groovy.xml.XmlSlurper

def xmlTxt = '''<root>
              <node>
                    <element/>
                    <element/>
                  </node>
            </root>'''
          
def xml = new XmlSlurper().parseText(xmlTxt)

xml.node.'*'.each {
    if ( it == "") {
        it.'@foo' = "bar"
    }
}
    
return XmlUtil.serialize(xml)

运行结果为:

<?xml version="1.0" encoding="UTF-8"?><root>
  <node>
    <element foo="bar"/>
    <element foo="bar"/>
  </node>
</root>

我的实际需求是将元素修改为<element xsi:nil="true"/>,其中xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"。我尝试在创建XmlSlurper实例时使用.declareNamespace(xsi:'http://www.w3.org/2001/XMLSchema-instance'),然后在添加属性时使用it.'@xsi:nil' = 'true',但这会导致错误。请问有没有使用现有语法快速实现的方法?


解决方案

直接通过XmlSlurper处理带命名空间的属性时,不需要提前声明命名空间,改用attributes().put()方法即可避开报错,具体实现有两种方式:

方式1:在每个空元素上声明命名空间

import groovy.xml.XmlUtil
import groovy.xml.XmlSlurper

def xmlTxt = '''<root>
              <node>
                    <element/>
                    <element/>
                  </node>
            </root>'''
          
def xml = new XmlSlurper().parseText(xmlTxt)

xml.node.'*'.each { elem ->
    if (elem == "") {
        elem.attributes().put("xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance")
        elem.attributes().put("xsi:nil", "true")
    }
}
    
return XmlUtil.serialize(xml)

运行结果

<?xml version="1.0" encoding="UTF-8"?><root>
  <node>
    <element xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:nil="true"/>
    <element xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:nil="true"/>
  </node>
</root>

方式2:在根节点统一声明命名空间(更规范)

如果希望命名空间只在根节点声明,避免重复,可以先给根节点添加命名空间属性,再给空元素添加xsi:nil:

import groovy.xml.XmlUtil
import groovy.xml.XmlSlurper

def xmlTxt = '''<root>
              <node>
                    <element/>
                    <element/>
                  </node>
            </root>'''
          
def xml = new XmlSlurper().parseText(xmlTxt)

// 根节点添加xsi命名空间
xml.attributes().put("xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance")

xml.node.'*'.each { elem ->
    if (elem == "") {
        elem.attributes().put("xsi:nil", "true")
    }
}
    
return XmlUtil.serialize(xml)

运行结果

<?xml version="1.0" encoding="UTF-8"?><root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <node>
    <element xsi:nil="true"/>
    <element xsi:nil="true"/>
  </node>
</root>

内容的提问来源于stack exchange,提问作者Axel K.

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 06:05:14