如何从xml中检索属性

时间:2017-02-03 11:47:12

标签: xml groovy soapui

我第一次使用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?

谢谢,

3 个答案:

答案 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