1

Team, I am going through multiple XPATH tutorials, but not able to achieve the below expectation using one XPathExpression.

How to get PostpaidInformation --> ActiveValue and Date value of AccountNumber=AC-12 ..?

<params>
    <param>
        <value>
            <struct>
                <member>
                    <name>PrepaidInformation</name>
                    <value>
                        <struct>
                            <member>
                                <name>activationStatus</name>
                                <value>
                                    <boolean>1</boolean>
                                </value>
                            </member>
                        </struct>
                    </value>
                </member>
                <member>
                    <name>MixedInformation</name>
                    <value>
                        <struct>
                            <member>
                                <name>activationStatus</name>
                                <value>
                                    <boolean>0</boolean>
                                </value>
                            </member>
                        </struct>
                    </value>
                </member>
                <member>
                    <name>PostpaidInformation</name>
                    <value>
                        <array>
                            <data>
                                <value>
                                    <struct>
                                        <member>
                                            <name>ActiveValue</name>
                                            <value>
                                                <string>60</string>
                                            </value>
                                        </member>
                                        <member>
                                            <name>Date</name>
                                            <value>
                                                <string>20170225T12:00:00</string>
                                            </value>
                                        </member>
                                        <member>
                                            <name>AccountNumber</name>
                                            <value>
                                                <i4>AC-12</i4>
                                            </value>
                                        </member>
                                    </struct>
                                </value>
                                <value>
                                    <struct>
                                        <member>
                                            <name>ActiveValue</name>
                                            <value>
                                                <string>23</string>
                                            </value>
                                        </member>
                                        <member>
                                            <name>Date</name>
                                            <value>
                                                <string>20170225T12:00:00</string>
                                            </value>
                                        </member>
                                        <member>
                                            <name>AccountNumber</name>
                                            <value>
                                                <i4>AC-13</i4>
                                            </value>
                                        </member>
                                    </struct>
                                </value>
                            </data>
                        </array>
                    </value>
                </member>
            </struct>
        </value>
    </param>
</params>

Note i have to match PostpaidInformation, then match on AccountNumber = AC-12. If it matches prints all the information about that account.

Maybe what i need is //methodResponse/params/param/value/struct/member/name[text()=\"PostpaidInformation\"] TRAVERSE all the accounts within this till finding AccountNumber=AC-12, if found then back out one level from member/value to reach <struct> to iterate all the <member> inside that struct.

Expected Output is NodeSet of below to traverse.

                                    <member>
                                        <name>ActiveValue</name>
                                        <value>
                                            <string>60</string>
                                        </value>
                                    </member>
                                    <member>
                                        <name>Date</name>
                                        <value>
                                            <string>20170225T12:00:00</string>
                                        </value>
                                    </member>
                                    <member>
                                        <name>AccountNumber</name>
                                        <value>
                                            <i4>AC-12</i4>
                                        </value>
                                    </member>

Actual answer from

Anderson is

//member/name[text()="PostpaidInformation"]/following-sibling:: 
value/array/data/value/struct[member[name="AccountNumber"]/value/i4="AC-12"] 

har07 is

//member[name='PostpaidInformation']//struct[member[name='AccountNumber' and value/i4='AC-12']]/member
3
  • Could you update question with exact output you want to get? Commented Mar 6, 2017 at 10:16
  • @Andersson Updated Q. I just want a NodeSet of name=PrepaidInformation ../array/data/value/struct for AccountNumber=AC-12. Commented Mar 6, 2017 at 10:20
  • w3.org/TR/xpath Commented Mar 8, 2017 at 6:03

2 Answers 2

1

Could you try:

//member/name[text()="PostpaidInformation"][1]/following-sibling::value/array/data/value/struct/member

This XPath should return 3 member nodes:

<member>
    <name>ActiveValue</name>
    <value>
         <string>60</string>
    </value>
</member>
<member>
   <name>Date</name>
   <value>
        <string>20170225T12:00:00</string>
   </value>
</member>
<member>
   <name>AccountNumber</name>
   <value>
        <i4>AC-12</i4>
   </value>
</member>

If you want to retrieve <struct> that contains those 3 <member>:

//member/name[text()="PostpaidInformation"]/following-sibling::value/array/data/value/struct[member[name[.="AccountNumber"]/following-sibling::value/i4="AC-12"]]
Sign up to request clarification or add additional context in comments.

8 Comments

Thank you! And where is the match for AC-12 among the array..? i think [1] is index of the array ..? then i am not sure AC-12 will always be array index [1]. Please help.
You mean you want to match first <name>PostpaidInformation</name> only if following <value> sibling has Account number = "AC-12"?
No. <name>PostpaidInformation</name> will be only one. But that contains multiple accounts. among that how to match a account which has Account number = "AC-12" ..?
Does this do a trick //member/name[text()="PostpaidInformation"][1]/following-sibling::value/array/data/value/struct[./member/value/i4="AC-12"]/member?
Sure i will check and revert you in 2 mins, but what is [1] here at text()="PostpaidInformation"][1]
|
1

This is one possible XPath (wrapped for readability) :

//member[name='PostpaidInformation']
//struct[member[name='AccountNumber' and value/i4='AC-12']]
/member

demo

brief explanation :

  • //member[name='PostpaidInformation'] : search for member element where name child value equals 'PostpaidInformation'

  • //struct[member[name='AccountNumber' and value/i4='AC-12']] : within such member element, search for descendant struct element containing child element member where name equals 'AccountNumber' and value/i4 equals 'AC-12'

  • /member : from such struct, return all child elements named member

2 Comments

Thank you for your explanations.
Yours is neat and clean :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.