Search code examples
node.jsgroovyxml-parsingready-api

how to get child node value from a paren preferenced by another child value in Groovy readyAPI


I am trying to get values from a web service response in readyAPI, so i can pass it to another web service request, so i can create a automated test flow.

I have tried different code pieces most of them was a single line of code, which i prefer if it possible. I can take value from a node by typing the parent node by its attribute value. I also can get parent node by child nodes attribute value and use it to get another child value.

Here some examples:

First Format that I can use it to get childs value:

<webserviceResponse>
<documentslist>
<document @id="1">
        <payment @currency="USD" >
        <amount>1250.00</amount>
        </payment>
</document>
<document @id="2">
        <payment @currency="JPY" >
        <amount>150.00</amount>
        </payment>
</document>
<document @id="3">
        <payment @currency="EUR" >
        <amount>1170.00</amount>
        </payment>
</document>
<!-- etc. -->
</documentslist>

-----> To get currency for a specific document

def webServiceResponse = "webservice#Response"
int index=2
def currency = context.expand('${'+webServiceResponse+'//*:document[@id="['+index+']"]//*:payment/@currency}')

-----> Result of this is "JPY"


<webserviceResponse>
<documentslist>
<document @id="1">
        <payment @currency="USD" >
        <amount>1250.00</amount>
        </payment>
        <refund>true</refund>
</document>
<document @id="2">
        <payment @currency="JPY" >
        <amount>150.00</amount>
        </payment>
</document>
<document @id="3">
        <payment @currency="EUR" >
        <amount>1170.00</amount>
        </payment>
        <refund>false</refund>
</document>
<!-- etc. -->
</documentslist>

-------> To get a currency dependent on existence of a specific node In this example we are looking the file from up to down and we are finding every refund nodes, and taking currency value that is in the same block with the second time we see a refund node.

def webServiceResponse = "webservice#Response"
int index=2
def currrency= context.expand('${'+webServiceResponse+'(//*:refund)['+index+']//parent::*//*:payment/@currency}')

--------> Result for this is "EUR"


This one is that i cant take child value with the same way.

<webserviceResponse>
<documentslist>
<document>
    <key>D_Computer</key>
    <currency>USD</currency>
    <amount>1250.00</amount>
    <refund>true</refund>
</document>
<document>
    <key>D_Keyboard</key>
    <currency>JPY</currency>
    <amount>150.00</amount>
</document>
<document>
    <key>D_Monitor</key>
    <currency>EUR</currency>
    <amount>1170.00</amount>
    <refund>false</refund>
</document>
<!-- etc. -->
</documentslist>

My problem with this one it doesn't have any attributes, has only values of the nodes. I know that it doesnt have an integer by the way but maybe i am doing wrong that i dont realize.

I want to get the amount value only dependent to the "key" nodes value which i am going to specify in the script.

result should show :150.00


Solution

  • Thank you for the very detailed and well written question.

    You can use the below. Your problem is easy as there are no namespace in it.

    Technique is same which you have dispalyed, its just that you need not to use @ as its for attributes

    def groovyUtils=new com.eviware.soapui.support.GroovyUtils(context)
    def xml=groovyUtils.getXmlHolder("NameOfRequest#Response");
    def currency=xml.getNodeValue("//*:documentslist/*:document[key='${key}']/*:amount");
    log.info "Value of $key  is " + currency
    
    key="D_Monitor"
    currency=xml.getNodeValue("//*:documentslist/*:document[key='${key}']/*:amount");
    log.info "Value of $key  is " + currency
    

    Replace NameOfRequest with your Request's name

    enter image description here

    There is an alternative way too. I will post it as a separate answer so not to cause confusion. This one is still better than other one