Reputation: 4324
I am using XMLParser for the first time to retrieve a response from an xml:
Below is the code:
import groovy.xml.XmlUtil
def response = testRunner.testCase.getTestStepByName("GetTestStep").getProperty("Response").getValue();
def root = new XmlParser().parseText( response )
log.info root
The log.info of root displays the following xml response:
:{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/}
Now I want to be able to retrieve the attribute for AvailabilityRS
, However I keep getting a blank [] when I try to retrieve it via this method:
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">
How can I retrieve the Url within the attribute for AvailabilityRS?
Thanks,
Upvotes: 1
Views: 3477
Reputation: 4482
The following works:
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
note the at @
character prefix for attribute values. If the attribute is hyphenated or otherwise not a valid groovy identifier, you can use a quoted node.'@attribute-name'
instead.
Note that the expression xml.'soap:Body'.HotelAvailResponse
returns a list of nodes which is why I added a [0]
to both expressions. The sentiment is that there could be any number of HotelAvailResponse nodes and groovy therefore returns a list even if there is just one node. Running the above without the [0]
indexing will return a list with the url as an element.
Note also that the result of an attribute access via the @
character is a string and not an xml node.
Upvotes: 3
Reputation: 246754
Some experimentation based on the two answers provided so far.
These all provide the same result: [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
Upvotes: 1
Reputation: 21359
Change your script to below, to retrieve the Url
:
Note that @
needs to be used to retrieve attributes.
def response = testRunner.testCase.getTestStepByName("GetHotelAvailability").getProperty("Response").getValue()
def parsedXml = new XmlSlurper().parseText(xml)
def url = parsedXml.'**'.find{ it.name() == 'AvailabilityRS' }[email protected]()
log.info "Url is :${url}"
Upvotes: 2