Joe F.
Joe F.

Reputation: 867

Parsing XML for specific item using ElementTree

I am making a request to the Salesforce merge API and getting a response like this:

xml_result = '<?xml version="1.0" encoding="UTF-8"?>
    <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns="urn:partner.soap.sforce.com">
    <soapenv:Header>
        <LimitInfoHeader>
            <limitInfo>
                <current>62303</current>
                <limit>2680000</limit><type>API REQUESTS</type></limitInfo>
        </LimitInfoHeader>
    </soapenv:Header>
    <soapenv:Body>
        <mergeResponse>
            <result>
                <errors>
                    <message>invalid record type</message>  
                    <statusCode>INSUFFICIENT_ACCESS_ON_CROSS_REFERENCE_ENTITY</statusCode>
                </errors>
                <id>003skdjf494244</id>
                <success>false</success>
           </result>
        </mergeResponse>
    </soapenv:Body>
</soapenv:Envelope>'

I'd like to be able to parse this response and if success=false, return the errors, statusCode, and the message text.

I've tried the following:

import xml.etree.ElementTree as ET
tree = ET.fromstring(xml_result)

root.find('mergeResponse')
root.find('{urn:partner.soap.sforce.com}mergeResponse')
root.findtext('mergeResponse')
root.findall('{urn:partner.soap.sforce.com}mergeResponse')

...and a bunch of other variations of find, findtext and findall but I can't seem to get these to return any results. Here's where I get stuck. I've tried to follow the ElementTree docs, but I don't understand how to parse the tree for specific elements.

Upvotes: 0

Views: 787

Answers (1)

Hendrik Makait
Hendrik Makait

Reputation: 1052

Element.find() finds the first child with a particular tag https://docs.python.org/2/library/xml.etree.elementtree.html#finding-interesting-elements

Since mergeResponse is a descendant, not a child, you should use XPath-syntax in this case:

root.find('.//{urn:partner.soap.sforce.com}mergeResponse')

will return your node. .// searches all descendants starting with the current node (in this case the root).

Upvotes: 1

Related Questions