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

How to add a namespace to an XML attribute using XmlSlurper (Apache Groovy)?

提问人:Axel K. 提问时间:9/21/2023 更新时间:9/27/2023 访问量:42

问:

我正在遍历扁平 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>

现在,我真正的要求是更改元素,以便 ,其中 xmlns:xsi=“http://www.w3.org/2001/XMLSchema-instance”<element xsi:nil="true"/>

我尝试在创建 XmlSlurper 实例时使用,然后在添加属性时使用,但这会导致错误。有没有一种快速的方法可以使用我使用的语法来实现这一点?.declareNamespace(xsi:'http://www.w3.org/2001/XMLSchema-instance')it.'@xsi:nil' = 'true'

Groovy Grails xml-namespaces xml-attribute xmlslurper

评论

0赞 chubbsondubs 9/22/2023
通常,您需要执行以下操作:其中 x 是要使用的命名空间名称,URL 是架构的值。我认为声明命名空间前缀会是有问题的。您是否尝试过使用其他前缀?.declareNamespace(x: 'http://www.groovy-lang.org')xsi
0赞 Axel K. 9/25/2023
在这里去做这件事

答:

0赞 chubbsondubs 9/27/2023 #1

这是我能想到的最好的:

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)

您遇到的问题是它不知道命名空间,因为它不在您的根节点定义中。使用 the 也不起作用,因为它没有看到该定义。我怀疑它是在解析后添加的,所以它看不到它。文档中提到了这一点。xsideclareNamespace

我尝试将命名空间定义直接放在XML中:

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

...但是当我将属性添加到元素时,它似乎仍然没有看到它。@xsi:nil

唯一有效的方法是将节点替换为包含定义的新定义节点。否则,它是“无界的”,并引发错误。xmlns:xsi

我还检查了它以不同的方式处理命名空间,但它的结果与 .如果你也想尝试它,我包括了代码。XmlParserXmlSlurper

这几乎是我能得到的。