Forum Discussion

Mis3's avatar
Mis3
Frequent Contributor
3 years ago

How to retrieve one particular parameter in an XML response of duplicate parameter name

Below is the response of an API I am working with.

There are a few sections of <balance> with identical parameter names.

Using this statement, def MESSAGE3 = xml.Body.GetSubscriberResponse.subscriber.balance.quota.code.flatten().join(' '), I can output all the balance.quota.code. In the example below, it outputs  XPLOR_INTERNATIONAL ROLLOVER_10 XPLOR_EXTENDED from the response.

Is there any way I can output only one of the parameters in the <balance> section to the log file; like ROLLOVER_10?   I 

Thanks.

 

<se:Envelope xmlns:se="http://schemas.xmlsoap.org/soap/envelope/">
<se:Body>
<GetSubscriberResponse xmlns="http://broadhop.com/unifiedapi/soap/types">
<errorCode>0</errorCode>
<errorMessage>Request completed successfully</errorMessage>
<subscriber>
<id>00710000b11e34346161b6d3</id>
<name>
<fullName>PTam</fullName>
</name>
<credential>
<networkId>3143140097</networkId>
<type>MSISDN</type>
</credential>
<service>
<code>DATA</code>
<enabled>true</enabled>
</service>
<service>
<code>ROAMING</code>
<enabled>true</enabled>
</service>
<service>
<code>VoLTE</code>
<enabled>true</enabled>
</service>
<service>
<code>SOS</code>
<enabled>true</enabled>
</service>
<balance>
<code>Xplor_International_Roaming</code>
<deprovisioned>false</deprovisioned>
<billCycle>21</billCycle>
<quota>
<code>XPLOR_INTERNATIONAL</code>
<credit>
<id>_kzyIwCkWEey4l9KX5DPT8w</id>
<initialAmount>109951162777600</initialAmount>
<amount>109951162777600</amount>
<reservedAmount>0</reservedAmount>
<startDate>2021-10-09T15:35:47.788Z</startDate>
<expirationDate>2021-10-20T23:59:59.999Z</expirationDate>
</credit>
<nextRefreshDate>2021-10-21T00:00:00.000Z</nextRefreshDate>
<recurrenceLimit>0</recurrenceLimit>
<totals>
<balance>109951162777600</balance>
<reserved>0</reserved>
<debited>0</debited>
</totals>
</quota>
<totals>
<balance>109951162777600</balance>
<reserved>0</reserved>
<debited>0</debited>
</totals>
</balance>
<balance>
<code>Xplor_Monthly</code>
<deprovisioned>false</deprovisioned>
<billCycle>21</billCycle>
<quota>
<code>ROLLOVER_10</code>
<credit>
<id>_kzxhsCkWEey4l9KX5DPT8w</id>
<initialAmount>10737418240</initialAmount>
<amount>10737418240</amount>
<reservedAmount>0</reservedAmount>
<startDate>2021-10-09T15:35:47.787Z</startDate>
<expirationDate>2021-10-20T23:59:59.999Z</expirationDate>
<rolloverPeriodAmount>1</rolloverPeriodAmount>
<rolloverPeriodUnits>Month</rolloverPeriodUnits>
<rolloverExpirationDate>2021-11-21T00:00:00.000Z</rolloverExpirationDate>
<rolloverTemplateName>MONTH_ROLLOVER</rolloverTemplateName>
</credit>
<nextRefreshDate>2021-10-21T00:00:00.000Z</nextRefreshDate>
<recurrenceLimit>0</recurrenceLimit>
<totals>
<balance>10737418240</balance>
<reserved>0</reserved>
<debited>0</debited>
</totals>
</quota>
<totals>
<balance>10737418240</balance>
<reserved>0</reserved>
<debited>0</debited>
</totals>
</balance>
<balance>
<code>Extended_Quota_Monthly</code>
<deprovisioned>false</deprovisioned>
<billCycle>21</billCycle>
<quota>
<code>XPLOR_EXTENDED</code>
<credit>
<id>_kzxhsSkWEey4l9KX5DPT8w</id>
<initialAmount>109951162777600</initialAmount>
<amount>109951162777600</amount>
<reservedAmount>0</reservedAmount>
<startDate>2021-10-09T15:35:47.787Z</startDate>
<expirationDate>2021-10-20T23:59:59.999Z</expirationDate>
</credit>
<nextRefreshDate>2021-10-21T00:00:00.000Z</nextRefreshDate>
<recurrenceLimit>0</recurrenceLimit>
<totals>
<balance>109951162777600</balance>
<reserved>0</reserved>
<debited>0</debited>
</totals>
</quota>
<totals>
<balance>109951162777600</balance>
<reserved>0</reserved>
<debited>0</debited>
</totals>
</balance>
<status>ACTIVE</status>
<startDate>2020-11-21T00:00:00.000Z</startDate>
<avp>
<code>profileKey</code>
<value>NORMAL</value>
</avp>
<version>0</version>
</subscriber>
</GetSubscriberResponse>
</se:Body>
</se:Envelope>

  • Hey Mis3,

    Im on my phone so i cant try and replicate in ReadyAPI, but i notice youre not using indices in your xpath, hence the reason im guessing youre retrieving all the values that correspond to the code elements' values, rather than just a single value.

    Im a bit out or practice cos ive been purely json for the last 3 years, but in your xpath:

    xml.Body.GetSubscriberResponse.subscriber.balance.quota.code whereas i think if you add an index, this indicates which balance element is the correct parent in the tree for the code element value you want.

    I cant really see the repeating structure properly on my phone and someone else will be able to confirm or deny this, but if in your xpath, rather than:

    xml.Body.GetSubscriberResponse.subscriber.balance.quota.code

    You instead add:

    xml.Body.GetSubscriberResponse.subscriber.balance[1].quota.code then this will result in grabbing the code elements value that is a child of the first instance of the balance element (i.e. 'XPLOR_INTERNATIONAL')

    Likewise if you wanted the 2nd code elements value:

    xml.Body.GetSubscriberResponse.subscriber.balance[2].quota.code

    This will result in grabbing the code elements value that is a child of the second instance of the balance element (i.e.'ROLLOVER_10')

    Likewise if you wanted the 3rd code elements value:

    xml.Body.GetSubscriberResponse.subscriber.balance[3].quota.code

    This will result in grabbing the code elements value that is a child of the third instance of the balance element (i.e.'XPLOR_EXTENDED')

    As i say....been quite a while since i was scripting with xml, but i remember its something like the above.

    Hope this helps,

    Rich
  • richie's avatar
    richie
    Community Hero
    Hey Mis3,

    Im on my phone so i cant try and replicate in ReadyAPI, but i notice youre not using indices in your xpath, hence the reason im guessing youre retrieving all the values that correspond to the code elements' values, rather than just a single value.

    Im a bit out or practice cos ive been purely json for the last 3 years, but in your xpath:

    xml.Body.GetSubscriberResponse.subscriber.balance.quota.code whereas i think if you add an index, this indicates which balance element is the correct parent in the tree for the code element value you want.

    I cant really see the repeating structure properly on my phone and someone else will be able to confirm or deny this, but if in your xpath, rather than:

    xml.Body.GetSubscriberResponse.subscriber.balance.quota.code

    You instead add:

    xml.Body.GetSubscriberResponse.subscriber.balance[1].quota.code then this will result in grabbing the code elements value that is a child of the first instance of the balance element (i.e. 'XPLOR_INTERNATIONAL')

    Likewise if you wanted the 2nd code elements value:

    xml.Body.GetSubscriberResponse.subscriber.balance[2].quota.code

    This will result in grabbing the code elements value that is a child of the second instance of the balance element (i.e.'ROLLOVER_10')

    Likewise if you wanted the 3rd code elements value:

    xml.Body.GetSubscriberResponse.subscriber.balance[3].quota.code

    This will result in grabbing the code elements value that is a child of the third instance of the balance element (i.e.'XPLOR_EXTENDED')

    As i say....been quite a while since i was scripting with xml, but i remember its something like the above.

    Hope this helps,

    Rich
    • Mis3's avatar
      Mis3
      Frequent Contributor

      Thanks.  Your suggestion worked but I ran into some complications.

       

      I saw that when I ran the Groovy for many subscribers, depending on the subscribers, the API responses can have different numbers of <balance>.    In my example in the original post, there are 3 balances:  XPLOR_INTERNATIONAL, Xplor_Monthly and Extended_Quota_Monthly.  There are other responses which have 2 balances and some have 4 balances.

       

      Another complication is the balance sections of the responses are not aligned.    In my example, Xplor_Monthly is the 2nd entry of the <balance>, turns out that it can be in the 1st, 3rd or even 4th entry of <balance>.

       

      I guess what I have to do is:

      1.  Find out how many sections of <Balance>:  def MESSAGE10 = xml.Body.GetSubscriberResponse.subscriber.balance.size() 

      2.  Check if the balance[x].code starting from x=0

      3.  If balance[x].code = "Xplor_Monthly", output balance[x].quota.code.  Else, check with x=x+1

       

      Not sure if there is a better way.

      Thanks.

       

       

      • Mis3's avatar
        Mis3
        Frequent Contributor

        Got it done.   Thanks for your help.

         

        I did this:

        def MESSAGE8 = ""
        def xx = xml.Body.GetSubscriberResponse.subscriber.balance.size()
        for(int k =0; k < xx; k++)
        {
        MESSAGE7 = xml.Body.GetSubscriberResponse.subscriber.balance[k].code
        if (MESSAGE7 == 'Xplor_Monthly' )
        {
        MESSAGE8 = xml.Body.GetSubscriberResponse.subscriber.balance[k].quota[0].code
        break
        }
        }