如何使用XmlSlurper(Apache Groovy)向XML属性添加命名空间?

hkmswyz6  于 7个月前  发布在  Apache
关注(0)|答案(1)|浏览(91)

我正在遍历一个扁平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',但这会导致错误。有没有一种快速的方法可以用我正在使用的语法来完成这一点?

kxeu7u2r

kxeu7u2r1#

这是我能想到的最好的:

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也不起作用,因为它没有看到该定义。我怀疑它是在解析后添加的,所以它看不到它。在docs中有一些提到这一点。
我尝试将命名空间定义直接放在XML中:

def xmlTxt = '''
<root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <node>
        <element/>
        <element/>
    </node>
</root>'''

.但是当我向元素添加@xsi:nil属性时,它似乎仍然没有看到它。
唯一起作用的是用包含xmlns:xsi定义的新定义的节点替换该节点。否则,它是“unbounded”并抛出错误。
我还检查了XmlParser,以防它处理名称空间的方式不同,但结果与XmlSlurper几乎相同。如果你也想用它来做实验的话,我会把代码包括在内。
这是我能做的最接近的了。

相关问题