我第一次使用XMLParser从xml中检索响应:
以下是代码:
import groovy.xml.XmlUtil
def response = testRunner.testCase.getTestStepByName("GetTestStep").getProperty("Response").getValue();
def root = new XmlParser().parseText( response )
log.info root
root的log.info显示以下xml响应:
:{http://schemas.xmlsoap.org/soap/envelope/}Envelope[attributes={}; value=[{http://schemas.xmlsoap.org/soap/envelope/}Body[attributes={}; value=[{http://www.xxx}TestHotelResponse[attributes={}; value=[{http://www.xxx}AvailabilityRS[attributes={Url=http://xxx.xxxxxxxx.com }; value=[{http://www.xxx.es/xxxxxx/2007/}
现在我希望能够检索AvailabilityRS
的属性,但是当我尝试通过此方法检索它时,我一直得到一个空白[]
root.AvailabilityRS*.value()*.each { k, v ->
log.info ("$k.localPart = $v")
}
RAW XML:
<soap:Envelope xmlns:soap="http://schemas.xxx">
<soap:Body>
<xxx xmlns="http://www.xxx7/">
<xxx Url="http://xxx.xxxxxx.com">
如何在AvailabilityRS的属性中检索Url?
谢谢,
答案 0 :(得分:3)
以下作品:
def str='''\
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<soap:Body>
<HotelAvailResponse xmlns="http://www.xxx/">
<AvailabilityRS Url="http://xxx.xxxxxx.com" TimeStamp="2017-02-03T11:14:30.5744079+00:00" IntCode="xxx" />
</HotelAvailResponse>
</soap:Body>
</soap:Envelope>
'''
def xml = new XmlParser().parseText(str)
def url = xml.'soap:Body'.HotelAvailResponse[0].AvailabilityRS[0].@Url
println url
请注意属性值的at @
字符前缀。如果属性是带连字符的,或者不是有效的常规标识符,则可以使用带引号的node.'@attribute-name'
代替。
请注意,表达式xml.'soap:Body'.HotelAvailResponse
返回节点列表,这就是我在两个表达式中添加[0]
的原因。情绪是可以有任意数量的HotelAvailResponse节点,因此即使只有一个节点,groovy也会返回一个列表。在没有[0]
索引的情况下运行上面的内容将返回一个列表,其中url作为元素。
另请注意,通过@
字符进行属性访问的结果是字符串而不是xml节点。
答案 1 :(得分:2)
将您的脚本更改为下方,以检索Url
:
请注意,@
需要用于检索属性。
def response = testRunner.testCase.getTestStepByName("GetHotelAvailability").getProperty("Response").getValue()
def parsedXml = new XmlSlurper().parseText(xml)
def url = parsedXml.'**'.find{ it.name() == 'AvailabilityRS' }.@Url.text()
log.info "Url is :${url}"
答案 2 :(得分:1)
基于迄今为止提供的两个答案的一些实验。
这些都提供相同的结果:[http://stagejuniperws.xxxxxx.com]
// if you know the exact path
println root.'soap:Body'.HotelAvailResponse[0].AvailabilityRS*.@Url
// verbose code
println root.depthFirst().inject([]) {urls, node ->
if (node.name().localPart == "AvailabilityRS") {
urls << node.@Url
}
urls
}
// more concise
println root.depthFirst().findAll {it.name().localPart == "AvailabilityRS"}*.@Url
// more concise, use the GPath symbol '**'
println root.'**'.findAll {it.name().localPart == "AvailabilityRS"}*.@Url
// more concise, more GPath
println root.'**'.AvailabilityRS*.@Url