Forum Discussion

DavidACollier's avatar
DavidACollier
New Contributor
9 years ago

Property Transfer with xpath of element based on child element

Hi, I'm attempting a property transfer in SoapUI NG, based on the XPath however it is not working for me. 

 

Taking this example response: 

 

<e>
    <id>f34f9f76-a4d9-412d-8407-f08299595f2a</id>
    <name>IronMan</name>
    <rank>1</rank>
</e>
<e>
    <id>a97f6768-d087-4993-9a48-1a20ae23d27f</id>
    <name>Thor</name>
    <rank>2</rank>
</e>
<e>
    <id>a0cf6c6e-31e3-4f28-98ec-33ae0d665e5d</id>
    <name>Hulk</name>
    <rank>3</rank>
</e>

 

If I use the "Get Data" Wizard to build my xpath from the ResponseAsXml, and grab the ID for Hulk, I get this and it works:

 

     //*:e[3]/*:id[1]

 

However I am not always guaranteed that it will be the third "e" element, so when I attempt to grab it based on the name, such as:

 

    //*:e[name='Hulk]/*:id[1]

 

It fails and returns null far as I know this should be the correct syntax, I have also tried:

   

    //*:e[name[text()='Hulk]]/*:id[1]

    //*:e[/name[text()='Hulk]]/*:id[1]

    //*:e[/name='Hulk']/*:id[1]

 

etc. Any help would be appreciated. 

 

 

  • nmrao's avatar
    nmrao
    9 years ago
    • Of course, every one has choice to choose different ways. Completely understand when it comes to comfortability.
    • I believe, we don't just stop there when hit a hard wall and keep going.
    • If you are ok with xpath as shown in the picture and having hard time, hope below xpath expression helps:

     

  • So after some more work I ended up doing the parsing for the data I need with Java instead of using the property transfer. In my setup I am using the soapUI test as library calls from my java code. 

     

    After some troubleshooting I started having similar issues in java for some responses and not others, and it turned to our to be my name space aware setting, and it looks like ReadyApi SoapNG has the same issue. 

     

    So basically, my response above had a namespace in it like this, (which i didn't post in my original post as I thought it was irrelevant)

     

    <Response xmlns="http://someUrl">

        <e>
            <id>f34f9f76-a4d9-412d-8407-f08299595f2a</id>
            <name>IronMan</name>
            <rank>1</rank>
        </e>
        <e>
            <id>a97f6768-d087-4993-9a48-1a20ae23d27f</id>
            <name>Thor</name>
            <rank>2</rank>
        </e>
        <e>
            <id>a0cf6c6e-31e3-4f28-98ec-33ae0d665e5d</id>
            <name>Hulk</name>
            <rank>3</rank>
        </e>

    </Response>

     

     

    In Java DocumentBuildFactory, when I set Name Space Aware to false, everything started working. So I tested this in ReadyAPI and it has the same issue. 

     

    Basically if I take a soap response that has no namespace (xmlns) value in then the data transfer works fine when I do something like, it gets the correct value:

     

        //*:e[name='Hulk]/*:id[1]

     

    However if the response has a namespace value, then it returns null.

     

    Is there a way around this or is this a bug?

        

    • nmrao's avatar
      nmrao
      Champion Level 3

      Not sure how you are using it exactly. However, it is very easy to process the same from groovy as shown below:

       

      /**
       * This script process the given xml string
       * and allows user to pass the known values (name as Hulk) and
       * retrieve the unknown(id)
       * */
      
      def searchData = { data, element, siblingElement, siblingElementValue -> 
          def slurper = new XmlSlurper().parseText(data)    
          slurper.'**'.find{ it.name() == siblingElement && it == siblingElementValue }.parent()."$element".text()
      }
      //Pass xml string here.
      log.info searchData(xml, 'id', 'name', 'Hulk')

       

      The above script can used in two different ways:

       

      1. as script assertion for same test stepSo, you can just change
        log.info searchData(xml, 'id', 'name', 'Hulk')
        to
        log.info searchData(context.response, 'id', 'name', 'Hulk')
      2. a separate groovy script test stepyou need to get the response into xml variable to be able to use the above script.

      NOTE: it should work for both namespace present and not.

      • DavidACollier's avatar
        DavidACollier
        New Contributor

        Thanks for the response and info, its good to know the options :)  Currently I am doing similar processing from my java code already so I think I'm good there for now, working with any full language its fairly easy. 

         

        I still think there is a bug here that would be nice to get fixed, would come in handy, and make some things easier. See the example screenshot, where I have a property transfer test step, I used the xpath builder to generate the xpath, then I replaced the "e[1]" (hardcoded index) with a valid xpath expression, "e[name='test2']"

         

        When the soap response has no namespace this works fine, when there is one you get null every time.