如何检查xml节点中的属性数组是否包含所需的值?

时间:2015-08-10 12:37:42

标签: arrays xml groovy

同事们,我有xml中的Node(Web服务的响应),它看起来像是:

<ns:addresses>
    <ns:address>
                <ns:addressType>PlaceOfRegistration</ns:addressType>
                 <ns:regionName>NewZeland</ns:regionName>
    </ns:address>
    <ns:address>
                   <ns:addressType>LivingPlace</ns:addressType>
                   <ns:regionName>Africa</ns:regionName>

    </ns:address>
</ns:addresses>

我需要检查:

  1. 如果LivingPlace存在于地址
  2. LivingPlace地址中的regionName不为空
  3. 我有一些尝试检查它但没有成功,因为我没有足够的Groovy经验。 我的代码是:

    def addressNodeCount = resp.getDomNodes("//ns:address//ns:addressType").size();
    log.info "Count: " + addressNodeCount; 
    
    //1 attempt
    for (def nodeIndex = 1; nodeIndex <=  addressNodeCount; nodeIndex++) {
       def node = resp.getDomNodes("//ns:address//ns:addressType")
       node.each { 
          log.info "node " + nodeIndex + " - " + it.firstChild.nodeValue
       }
    }
    
    //2 attempt
    for( item in resp.getDomNodes("//ns:address//ns:addressType"))
    log.info "Item : [$item]"
    
    你可以帮忙吗?

    UPDATE1

    完整的xml Web服务响应:

    <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
       <soap:Body>
          <ns:getPerson xmlns:ns="http://test.webservice.namespace">
             <ns:person>
                <ns:address>
                   <ns:addressType>LivingPlace</ns:addressType>
                   <ns:regionName>Africa</ns:regionName>
                </ns:address>
                <ns:address>
                   <ns:addressType>PlaceOfRegistration</ns:addressType>
                   <ns:regionName>NewZeland</ns:regionName>
                </ns:address>
                <ns:address>
                   <ns:addressType>LivingPlace</ns:addressType>
                   <ns:regionName>Europe</ns:regionName>
                </ns:address>
             </ns:person>
          </ns:getPerson>
       </soap:Body>
    </soap:Envelope>
    

1 个答案:

答案 0 :(得分:1)

如果您已将该项目作为节点,那么您应该能够:

yourNode.'address'.findAll { it.'addressType' == 'LivingPlace' && it.'regionName'.size() > 0 }

这是一个使用XmlSlurper的工作示例,其中有额外的项目来说明是否设置了regionName元素。

import groovy.util.XmlSlurper

class ParseXml {

    def static main(args) {
        new ParseXml().parse("""\
            |<ns:addresses xmlns:ns='http://foo.com'>
            |   <ns:address>
            |       <ns:addressType>PlaceOfRegistration</ns:addressType>
            |       <ns:regionName>NewZeland</ns:regionName>
            |   </ns:address>
            |   <ns:address>
            |       <ns:addressType>LivingPlace</ns:addressType>
            |       <ns:regionName>Africa</ns:regionName>
            |   </ns:address>
            |   <ns:address>
            |       <ns:addressType>LivingPlace</ns:addressType>
            |       <ns:notRegionName>Foo</ns:notRegionName>
            |   </ns:address>
            |   <ns:address>
            |       <ns:addressType>LivingPlace</ns:addressType>
            |       <ns:regionName>Europe</ns:regionName>
            |   </ns:address>
            |</ns:addresses>
            |""".stripMargin())
    }

    def parse(xml) {
        def s = new XmlSlurper().parseText(xml).declareNamespace(ns:'http://foo.com')
        s.'address'.findAll{ it.'addressType' == "LivingPlace" && it.'regionName'.size() > 0 }.each { n ->
            println n.'regionName'
        }
    }
}

输出:

Africa
Europe

修改

根据您的更新,以下内容将使用messageExchange.responseContentAsXml而不是XmlSlurper再次解析xml字符串XmlHolder

    def parse2(xml) {
        GPathResult result = new XmlSlurper().parseText(xml)

        result.with {
            declareNamespace(ns:   "http://test.webservice.namespace")
            declareNamespace(soap: "http://schemas.xmlsoap.org/soap/envelope/")
        }
        result.'Body'.'getPerson'.'person'.'address'.findAll{ it.'addressType' == "LivingPlace" && it.'regionName'.size() > 0 }.each { n ->
            println n.'regionName'
        }
    }

如果您需要使用XmlHolder的解决方案,请look at the API here。您的初始.getDomNodes()调用返回一个数组,而不是NodeList,因此它们在执行XML搜索和解析时的方式略有不同。