Driver XPath Get XML element value

I have the XML response in Driver's local variable 'lv-Result'.

<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns="urn:partner.soap.sforce.com" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:sf="urn:sobject.partner.soap.sforce.com">
    <soapenv:Header>
        <LimitInfoHeader>
            <limitInfo>
                <current>142795</current>
                <limit>49754000</limit>
                <type>API REQUESTS</type>
            </limitInfo>
        </LimitInfoHeader>
    </soapenv:Header>
    <soapenv:Body>
        <queryAllResponse>
            <result xsi:type="QueryResult">
                <done>true</done>
                <queryLocator xsi:nil="true"/>
                <records xsi:type="sf:sObject">
                    <sf:type>User</sf:type>
                    <sf:Id>005030000040AQeAAM</sf:Id>
                    <sf:Id>005030000040AQeAAM</sf:Id>
                </records>
                <size>1</size>
            </result>
        </queryAllResponse>
    </soapenv:Body>
</soapenv:Envelope>

I want to get the value of <sf:Id>005030000040AQeAAM</sf:Id> and <size>1</size>, please help here.

I tried the below XPath in Driver's local variable as String but got an error.

$lv-Result/*[local-name()="soapenv:Envelope"]/*[local-name()="soapenv:Body"]/queryAllResponse/result/size/text()

I am using IDM 4.7.3.

  • 0  

    Define the sf namespace in the policy, and then add in the sf: on the size node. 

    Or use the *[local-name()="size"] style thing, all the way through.

  • 0 in reply to   

    could you please guide me on what should be the URI for the 'sf' prefix namespace?

  • 0   in reply to 

    In Designer, you could flip to the XMLview, in the <policy> node, add this text inside the node like:
    <policy xmlns:sf="urn:sobject.partner.soap.sforce.com"?

    Or you could click the Namespace button on the Policy page where you use this XPATH expression (upper right, it is next to the Simulate button)

    And define the first field as sf and then the second field as urn:sobject.partner.soap.sforce.com

  • Verified Answer

    +1   in reply to   

    Here is a screen shot, for a POlicy editor page, I clicked on the Namespace icon, upper right, (see where my arrow is pointing) and moved the Namespace Editor underneath for a smaller screen shot.

    In the prefix, put sf

    In the URI put the urn:sobject.partner.soap.sforce.com value

    If you check the <policy> node, before and after the change, you will see it gets appended the full

    xmlns:sf="urn:sobject.partner.soap.sforce.com" value.

    Both ways are the same, just different approaches.

  • 0   in reply to   

    XPATH expressions (generated by XMLPad):

    for value:

    /soapenv:Envelope/soapenv:Body/queryAllResponse/result/records/sf:Id

    or /soapenv:Envelope/soapenv:Body/queryAllResponse/result/records/sf:Id[1]

    for size:

    /soapenv:Envelope/soapenv:Body/queryAllResponse/result/size

  • 0   in reply to   

    But for it to work, with a prefix, you have to define the namespaxce already.  So soapenv and sf need to be specified.  The *[local-name()="soapenv"] works well when the namespace may differ endpoint to endoiint.

  • 0   in reply to   

    Hello, today after a long time I had the time to look into this because it was really intriguing for me.

    And as you said, these two worked without defining namespace in policy:

    $lv-Result/*[local-name()="Envelope"]/*[local-name()="Body"]/*[local-name()="queryAllResponse"]/*[local-name()="result"]/*[local-name()="size"]
    $lv-Result/*[local-name()="Envelope"]/*[local-name()="Body"]/*[local-name()="queryAllResponse"]/*[local-name()="result"]/*[local-name()="records"]/*[local-name()="Id"]

    I can wrap my head around the fact that I could not use normal notation after namespace nodes, so this does not work:

    $lv-Result/*[local-name()="Envelope"]/*[local-name()="Body"]/queryAllResponse/result/size
    $lv-Result/*[local-name()="Envelope"]/*[local-name()="Body"]/queryAllResponse/result/records/Id

    But then to use "normal"/simple XPath notation I defined "soapenv" as you specified and this worked:

    $lv-Result/soapenv:Envelope/soapenv:Body

    but going further with nodes without namespace, I was not able to select them (this did not work)

    $lv-Result/soapenv:Envelope/soapenv:Body/queryAllResponse

    I am guessing this does not work because children nodes are expected to have the same or different kind of namespace - not default one?

    What I did to make it work is this

    $lv-Result/soapenv:Envelope/soapenv:Body/*[local-name()="queryAllResponse" and namespace-uri()="urn:partner.soap.sforce.com"]

    This works but is nasty/cumbersome, but it makes sure the "queryAllResponse" node is selected and only the one with the default namespace! I find it a bit weird that the default namespace cannot be selected if parent uses a different namespace. (this last sentence is more for future searches, especially mine Joy)

    Any feedback will be greatly appreciated. Grin