Parse XML response in SoapUI using groovy

17,321

Solution 1

dmahapatro's answer is correct based on the xml you had original provided. The parsed xml is set to root node. It would have really helped if you had provided the original xml earlier and what you were getting as a response.

You also asked why you were getting

{http://www.w3.org/2003/05/soap-envelope}Envelope[attributes={}; value=[{http://www.w3.org/2003/05/soap-envelope}Body[attributes={}; value=[{http://www.opentravel.org/OTA/2003/05}OTA_HotelAvailRS[attributes={TimeStamp=2014-04-01T16:09:25, Target=Production, Version=1}; value=[{http://www.opentravel.org/OTA/2003/05}Success[attributes={}; value=[]], {http://www.opentravel.org/OTA/2003/05}RoomStays[attributes={}; value=[{http://www.opentravel.org/OTA/2003/05}RoomStay[attributes={}; value=[{http://www.opentravel.org/OTA/2003/05}RoomTypes[attributes={}; value=[{http://www.opentravel.org/OTA/2003/05}RoomType[attributes={RoomTypeCode=AAA, RoomID=AA, Quantity=9}; value=[{http://www.opentravel.org/OTA/2003/05}RoomDescription[attributes={}; value=[{http://www.opentravel.org/OTA/2003/05}Text[attributes={}; value=[Double Room - Room only]]]]]], {http://www.opentravel.org/OTA/2003/05}RoomType[attributes={RoomTypeCode=BBB, RoomID=BB, Quantity=9}; value=[{http://www.opentravel.org/OTA/2003/05}RoomDescription[attributes={}; value=[{http://www.opentravel.org/OTA/2003/05}Text[attributes={}; value=[Double Room - Bed and Breakfast]]]]]], {http://www.opentravel.org/OTA/2003/05}RoomType[attributes={RoomTypeCode=CCC, RoomID=CC, Quantity=9}; value=[{http://www.opentravel.org/OTA/2003/05}RoomDescription[attributes={}; value=[{http://www.opentravel.org/OTA/2003/05}Text[attributes={}; value=[Executive Family Room - Room only]]]]]], {http://www.opentravel.org/OTA/2003/05}RoomType[attributes={RoomTypeCode=DDD, RoomID=DD, Quantity=9}; value=[{http://www.opentravel.org/OTA/2003/05}RoomDescription[attributes={}; value=[{http://www.opentravel.org/OTA/2003/05}Text[attributes={}; value=[Executive Family Room - Bed and Breakfast]]]]]]]], {http://www.opentravel.org/OTA/2003/05}GuestCounts[attributes={}; value=[{http://www.opentravel.org/OTA/2003/05}GuestCount[attributes={AgeQualifyingCode=10, Count=2}; value=[]]]], {http://www.opentravel.org/OTA/2003/05}TimeSpan[attributes={Start=2014-06-29, Duration=P3N}; value=[]], {http://www.opentravel.org/OTA/2003/05}BasicPropertyInfo[attributes={ChainCode=GDF, HotelCode=1234, HotelName=ABC Resort}; value=[]], {http://www.opentravel.org/OTA/2003/05}TPA_Extensions[attributes={}; value=[{http://www.opentravel.org/OTA/2003/05}SortOrder[attributes={}; value=[1]]]]]]]]]]]]]]

The parser.parseText (response) code returns a node and the definition of a node states.

Represents an arbitrary tree node which can be used for structured metadata or any arbitrary XML-like tree. A node can have a name, a value and an optional Map of attributes

If you look closely what you got is a node with name, a value and an optional map of attributes, a case in point..

RoomType[attributes={RoomTypeCode=BBB, RoomID=BB, Quantity=9}; value=[{http://www.opentravel.org/OTA/2003/05}RoomDescription[attributes={}; value=[{http://www.opentravel.org/OTA/2003/05}Text[attributes={}; value=[Double Room - Bed and Breakfast]

which represents the below part of the xml.

<RoomType RoomTypeCode="BBB" RoomID="BB" Quantity="9">
    <RoomDescription>
        <Text>Double Room - Bed and Breakfast</Text>
    </RoomDescription>
</RoomType>

Based on your original xml try the below code to access each room type

//I put your xml in a test request step as a request, this code will work even if it is in the response.
def response = context.expand('${Test Request#Request}')

//the xml uses namespaces so they have to be declared
def soap = new groovy.xml.Namespace("http://www.w3.org/2003/05/soap-envelope", 'soap')
def ns = new groovy.xml.Namespace("http://www.opentravel.org/OTA/2003/05", 'ns')

XmlParser parser = new XmlParser()
def root = parser.parseText (response)

def rt = root[soap.Body][ns.OTA_HotelAvailRS][ns.RoomStays][ns.RoomStay][ns.RoomTypes][ns.RoomType]

assert rt != null

rt.each { RoomType ->
    log.info "${RoomType.'@RoomTypeCode'} ${RoomType.'@RoomID'}"
}

This gives me

Wed Apr 02 10:13:34 ADT 2014:INFO:AAA AA
Wed Apr 02 10:13:34 ADT 2014:INFO:BBB BB
Wed Apr 02 10:13:34 ADT 2014:INFO:CCC CC
Wed Apr 02 10:13:34 ADT 2014:INFO:DDD DD

Solution 2

Should be

responseParser.RoomStay.RoomTypes.RoomType.each { RoomType ->
   log.info "${RoomType.'@RoomTypeCode'} ${RoomType.'@RoomID'}"
}

Note: RoomStays is the root and is not used, as the parsed xml is set to that node.

Share:
17,321
user3463885
Author by

user3463885

Updated on June 04, 2022

Comments

  • user3463885
    user3463885 almost 2 years

    I want to parse a XML response in SoapUI. I have below script, but somehow I am not able to parse. Could you anyone please help me to refine the code.

    def response = context.expand( '${WS_01_Hotel_Search#Response#declare namespace soap=\'http://www.w3.org/2003/05/soap-envelope\'; //OTA_HotelAvailRS[1]/RoomStays[1]}' )
    def responseParser = new XmlParser().parseText(response)
    
    responseParser.RoomStays.RoomStay.RoomTypes.RoomType.each { RoomType ->
       log.info("${RoomType.'@RoomTypeCode'} ${RoomType.'@RoomID'}");
    }
    

    XML Code:

    <RoomStays>
        <RoomStay>
           <RoomTypes>
              <RoomType RoomTypeCode="AAA" RoomID="BB" Quantity="9">
                 <RoomDescription>
                    <Text>Double Room</Text>
                 </RoomDescription>
              </RoomType>
              <RoomType RoomTypeCode="BBB" RoomID="CC" Quantity="9">
                 <RoomDescription>
                    <Text>Double Room</Text>
                 </RoomDescription>
              </RoomType>
              <RoomType RoomTypeCode="CCC" RoomID="DD" Quantity="9">
                 <RoomDescription>
                    <Text>Executive Family Room</Text>
                 </RoomDescription>
              </RoomType>
              <RoomType RoomTypeCode="DDD" RoomID="EE" Quantity="9">
                 <RoomDescription>
                    <Text>Executive Family Room</Text>
                 </RoomDescription>
              </RoomType>
           </RoomTypes>                             
        </RoomStay>
     </RoomStays>