1

I've been following the examples from HERE and HERE trying parse a SOAP response, but not able to get the element I want.

Example SOAP Response:

<?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">
    <soapenv:Body>
        <loginResponse>
            <result>
                <metadataServerUrl>meta</metadataServerUrl>
                <passwordExpired>false</passwordExpired>
                <sandbox>true</sandbox>
                <serverUrl>someUrl</serverUrl>
                <sessionId>sessionId###</sessionId>
                <userId>userId###</userId>
                <userInfo></userId>
            </result>
        </loginResponse>
    </soapenv:Body>
</soapenv:Envelope>

Trying to get the sessionId but getting None or empty list back.

Example Code:

import xml.etree.ElementTree as ET

...


r = requests.post(url, headers=header, data=payload)

data = r.content

ns = {
    "soapenv": "http://schemas.xmlsoap.org/soap/envelope/"
}

root = ET.fromstring(data)

sid = root.findall(".//soapenv:sessionId", ns)

# Tried these and any combination of those
#sid = root.findall("./soapenv:Body/soapenv:loginResponse/soapenv:result/soapenv:sessionId", ns)
#sid = root.findall("./soapenv:Body/loginResponse/result/sessionId", ns)
#sid = root.findall("soapenv:sessionId", ns)

print(sid)

Can anyone help with this?

YTKColumba
  • 43
  • 3
  • 6

1 Answers1

0

You've been trying to search for a wrong ns.

Here is working example:

import xml.etree.ElementTree as ET

data = """<?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">
    <soapenv:Body>
        <loginResponse>
            <result>
                <metadataServerUrl>meta</metadataServerUrl>
                <passwordExpired>false</passwordExpired>
                <sandbox>true</sandbox>
                <serverUrl>someUrl</serverUrl>
                <sessionId>sessionId###</sessionId>
                <userId>userId###</userId>
                <userInfo></userInfo>
            </result>
        </loginResponse>
    </soapenv:Body>
</soapenv:Envelope>"""

root = ET.fromstring(data)

sid = root.findall(".//{urn:partner.soap.sforce.com}sessionId")
print(sid[0].text)
Sergey Nudnov
  • 833
  • 6
  • 12
  • hi @Sergey, would you mind explaining why `urn:partner.soap.sforce.com` is the namespace instead of `soapenv` since `Body is also prefixed with `soapenv`? – YTKColumba May 17 '19 at 17:54
  • 1
    @YTKColumba I don't know XML theory very well. IMHO `xmlns` parameter is a default name space for the keys, `xmlns:...` are additional namespaces. For a key to be in additional namespace, it should be prepended with the additional namespace's name. All other keys are in default namespace. I got to the answer by looking at output of `root.findall(".//")` – Sergey Nudnov May 17 '19 at 18:17