我正在迭代扁平化 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'
,但这会导致错误。有没有一种快速的方法可以使用我正在使用的语法来完成此任务?
这是我能想到的最好的:
import groovy.xml.XmlUtil
import groovy.xml.MarkupBuilder
import groovy.xml.XmlSlurper
def xmlTxt = '''
<root>
<node>
<element/>
<element/>
</node>
</root>'''
def parseSlurper( text ) {
def xml = new XmlSlurper().parseText(text)
xml.node.'*'.replaceNode {
element('xsi:nil': true, "xmlns:xsi": "http://www.w3.org/2001/XMLSchema-instance")
}
// this should work, but doesn't. But it doesn't throw an error either.
// xml.node.'*'.each {
// it.'@xsi:nil' = true
// it.'xmlns:xsi' = "http://www.w3.org/2001/XMLSchema-instance"
// }
return xml
}
def parseXmlParser( text ) {
def xml = new XmlParser().parseText(text)
xml.node.'*'.each {
it.replaceNode {
element('xsi:nil': true, "xmlns:xsi": "http://www.w3.org/2001/XMLSchema-instance")
}
}
return xml
}
def xml = parseSlurper( xmlTxt )
//def xml = parseXmlParser( xmlTxt )
println XmlUtil.serialize(xml)
您遇到的问题是它不知道
xsi
命名空间,因为它不在您的根节点定义中。使用 declareNamespace
也不起作用,因为它没有看到该定义。我怀疑它是在解析后添加的,所以它看不到它。文档中有一些提到这一点。
我尝试将命名空间定义直接放入 XML 中:
def xmlTxt = '''
<root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<node>
<element/>
<element/>
</node>
</root>'''
...但是当我向元素添加
@xsi:nil
属性时,它似乎仍然没有看到它。
唯一有效的方法是将节点替换为包含
xmlns:xsi
定义的新定义节点。否则它是“无界”并抛出错误。
我还检查了
XmlParser
是否以不同方式处理名称空间,但结果与 XmlSlurper
几乎相同。如果您也想尝试一下,我提供了代码。
这就是我能得到的最接近的结果了。