Groovy+XML:处理带有命名空间前缀的属性

uxh89sit  于 2022-09-21  发布在  其他
关注(0)|答案(5)|浏览(282)

我正在使用Groovy处理一个XML文档,并测试某个节点的某个属性,该属性有一个名称空间前缀。它是如何工作的:

在groovy脚本中:

...
Element.Subelement.each {
  if (it.'@type'=='ns2:xyType')
    ...do what ever...
}

在XML文档中:

<Element>
   <Subelement xsi:type="ns2:xyType"> 
      <!-- or another type, want to do something with      
           subelement only if type is "ns2:xyType" -->
   </Subelement>
</Element>

寻找类似以下内容的内容:

if (it.'@xsi:type'=='ns2:xyType')

THX Seldon

zour9fqk

zour9fqk1#

您的文档有点令人困惑,因为XSI和NS2名称空间似乎都没有声明过,但我假设它们是在完整的文档中的某个地方声明的。

The Groovy Docs开始

def wsdl = '''
<definitions name="AgencyManagementService"
    xmlns:ns1="http://www.example.org/NS1"
    xmlns:ns2="http://www.example.org/NS2">
    <ns1:message name="SomeRequest">
        <ns1:part name="parameters" element="SomeReq" />
    </ns1:message>
    <ns2:message name="SomeRequest">
        <ns2:part name="parameters" element="SomeReq" />
    </ns2:message>
</definitions>
'''

def xml = new XmlSlurper().parseText(wsdl).declareNamespace(ns1: 'http://www.example.org/NS1', ns2: 'http://www.example.org/NS2')
println xml.'ns1:message'.'ns1:part'.size()
println xml.'ns2:message'.'ns2:part'.size()

对于您的示例(请注意,您必须填写名称空间的URL):

def ggg = '''
<Element xmlns:xsi="http://www.example.org/xsi"
    xmlns:ns2="http://www.example.org/NS2">
   <Subelement xsi:type="ns2:xyType"> 
      <SubSub name="bob" />
   </Subelement>
</Element>
'''
def xml = new XmlSlurper().parseText(ggg).declareNamespace(xsi: 'http://www.example.org/xsi', ns2: 'http://www.example.org/NS2')
def elem = xml.'Subelement'
if ( elem.'@xsi:type'.text() == 'ns2:xyType' ){
   // do it  
}
z9ju0rcb

z9ju0rcb2#

在官方文件中没有提到如何做到这一点,这是荒谬的。

以下是我发现的有效方法(Groovy 2.4)

def element = new XmlParser(false, false).parseText(xml)
assert element.Subelement.'@xsi:type' == 'ns2:xyType'

其中,在创建XmlSlurper或解析器时,为名称空间Aware传入False。

rn0zuynd

rn0zuynd3#

def xsi = new groovy.xml.Namespace("http://www.w3.org/2001/XMLSchema-instance")  
node.attributes()[xsi.type] == 'my_type'
kwvwclae

kwvwclae4#

这对我来说很好(groovy 1.8.4)。给定的XML文档为:

<container>
    <item xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="woo:FAMILY">
      <id>111</id>
      <name>Family 1</name>
   </item>
</container>

此Assert传递:

def xml = new XmlSlurper().parseText(xmlDocStr)
assert "woo:FAMILY" == xml.item.'@xsi:type'.text()

注意:不过,您确实必须拥有.text()。

uubf1zoe

uubf1zoe5#

您还可以在代码中重新创建完整的属性标识符(它是QName),并使用它来查找属性值:

final QName classAttributeKey = new QName("http://example.org/", "attributeKeyAKALocalPart", "prefix")
String attributeValue = yourNode.attribute(classAttributeKey)

相关问题