如何使用groovy脚本在XML子节点上循环

qvtsj1bj  于 6个月前  发布在  其他
关注(0)|答案(2)|浏览(77)

我有一个XML响应如下:

<ns:Envelope xmlns:tns="http://schemas.xmlsoap.org/soap/envelope/">
 <ns:Body>
    <ns:response xmlns:svc="http://...serviceNameSpace" 
                xmlns:ent="http://....entitiesNameSpace">
        <ns:customer>
            <ns:contact>
                <ns:type>firstclass</ns:type>
                <ns:email>[email protected]</ns:email>
                <ns:details>
                    <ns:name>Kevin</ns:name>
                    <ns:area>Networking</ns:area>
                </ns:details>
                <ns:address>
                    <ns:code>39343</ns:code>
                    <ns:country>US</ns:country>
                </ns:address>
             </ns:contact>
            <ns:contact>
                <ns:type>secondclass</ns:type>
                <ns:email>[email protected]</ns:email>
                <ns:details>
                    <ns:name>John</ns:name>
                    <ns:area>Development</ns:area>
                <ns:address>
                    <ns:code>23445</ns:code>
                    <ns:country>US</ns:country>
             </ns:contact>                 
        </ns:customer>
    </ns:response >
</ns:Body>

字符串
我尝试这样做是为了验证子节点的详细信息和地址,以便用请求属性验证响应。但我可以Assert电子邮件,但无法进入详细信息(名称和地区)和地址(代码和国家)。下面是我使用的代码

import groovy.xml.*

def envelope = new XmlSlurper().parseText(messageExchange.responseContentAsXml)
def type = 'secondclass'
def emailAddress= ${properties#emailAddress}

envelope.'**'
.findAll { it.name() == 'contact' }
.findAll { it.type.text().contains(type) }
.each {
        assert emailAddress== it.emailAddress.text()
    }


请帮助我迭代节点的详细信息(名称和区域)和地址(代码和国家)进行Assert

cidc1ykv

cidc1ykv1#

首先,你的xml似乎有一点小问题,因为缺少了结束标记。我在下面的例子中冒昧地修复了这个问题。
从概念上讲,当你使用xml.Envelope.Body.response这样的表达式在xml中导航时,你就是在xml节点中导航。注意xml节点(即元素)和节点中实际数据或文本之间的区别。
从XmlSlurper返回的xml节点表示为groovy GPathResult类的后代。这些后代包括NodeChild、NodeChildren、NoChildren和Attribute,所有这些都可以由xml.Envelope.Body.Response类型的查询返回,具体取决于查询和xml的外观。若要检索节点中的实际文本数据,需要调用node.text()
修复xml并记住上述内容后,以下代码:

def str = '''\
<ns:Envelope xmlns:ns="http://schemas.xmlsoap.org/soap/envelope/">
<ns:Body>
    <ns:response xmlns:svc="http://...serviceNameSpace" xmlns:ent="http://....entitiesNameSpace">
        <ns:customer>
            <ns:contact>
                <ns:type>firstclass</ns:type>
                <ns:email>[email protected]</ns:email>
                <ns:details>
                    <ns:name>Kevin</ns:name>
                    <ns:area>Networking</ns:area>
                </ns:details>
                <ns:address>
                    <ns:code>39343</ns:code>
                    <ns:country>US</ns:country>
                </ns:address>
             </ns:contact>
            <ns:contact>
                <ns:type>secondclass</ns:type>
                <ns:email>[email protected]</ns:email>
                <ns:details>
                    <ns:name>John</ns:name>
                    <ns:area>Development</ns:area>
                </ns:details>
                <ns:address>
                    <ns:code>23445</ns:code>
                    <ns:country>US</ns:country>
                </ns:address>
             </ns:contact>                 
        </ns:customer>
    </ns:response >
</ns:Body>
</ns:Envelope>
'''

def xml = new XmlSlurper(false, true).parseText(str)

def contactNodes = xml.Body.response.customer.contact

assert contactNodes.first().email               == '[email protected]'
assert contactNodes.first().details.name.text() == "Kevin"
assert contactNodes.first().details.area.text() == "Networking"

assert contactNodes.last().email               == '[email protected]'
assert contactNodes.last().details.name.text() == "John"
assert contactNodes.last().details.area.text() == "Development"

字符串
并且所有Assert都成功。“
contactNodes变量是一个groovy NodeChildren对象,可以被视为节点列表(也就是说,您可以在其上调用.each {}.every {}.any {}等方法)。

edit in response to comment:要只迭代具有特定属性的联系人节点,您可以执行以下操作:

xml.Body.response.customer.contact.findAll { contactNode ->
    contactNode.type.text() == 'firstclass' 
}.each { firstClassContactNode -> 
    assert firstClassContactNode.email.text() == "[email protected]"
}

kq0g1dla

kq0g1dla2#

首先通过filter type =“secondclass”得到“联系人”节点,然后根据第一步的结果,对每一项进行测试。
您的groovy脚本将像这样更改:

import groovy.xml.*
    
    def envelope = new XmlSlurper().parseText(messageExchange.responseContentAsXml);
    def type = 'secondclass';
    def emailAddress= ${properties#emailAddress};
    
    envelope.Body.response.customer.contact
         .findAll {contactNode -> contactNode.type.text() == type}
         .each{ currentNode -> assert emailAddress== currentNode.emailAddress.text()};

字符串

相关问题