简体   繁体   中英

ElementTree XML API not matching subelement

I am attempting to use the USPS API to return the status of package tracking. I have a method that returns an ElementTree.Element object built from the XML string returned from the USPS API.

This is the returned XML string.

<?xml version="1.0" encoding="UTF-8"?>
  <TrackResponse>
    <TrackInfo ID="EJ958088694US">
      <TrackSummary>The Postal Service could not locate the tracking information for your 
       request. Please verify your tracking number and try again later.</TrackSummary>
    </TrackInfo>
  </TrackResponse>

I format that into an Element object

response = xml.etree.ElementTree.fromstring(xml_str)

Now I can see in the xml string that the tag 'TrackSummary' exists and I would expect to be able to access that using ElementTree's find method.

As extra proof I can iterate over the response object and prove that the 'TrackSummary' tag exists.

for item in response.iter():
    print(item, item.text)

returns:

<Element 'TrackResponse' at 0x00000000041B4B38> None
<Element 'TrackInfo' at 0x00000000041B4AE8> None
<Element 'TrackSummary' at 0x00000000041B4B88> The Postal Service could not locate the tracking information for your request. Please verify your tracking number and try again later.

So here is the problem.

print(response.find('TrackSummary')

returns

None

Am I missing something here? Seems like I should be able to find that child element without a problem?

The .find() method only searches the next layer, not recursively. To search recursively, you need to use an XPath query. In XPath, the double slash // is a recursive search. Try this:

# returns a list of elements with tag TrackSummary
response.xpath('//TrackSummary')

# returns a list of the text contained in each TrackSummary tag
response.xpath('//TrackSummary/node()')
import xml.etree.cElementTree as ET # 15 to 20 time faster

response = ET.fromstring(str)

Xpath Syntax Selects all child elements. For example, */egg selects all grandchildren named egg.

element = response.findall('*/TrackSummary') # you will get a list
print element[0].text #fast print else iterate the list

>>> The Postal Service could not locate the tracking informationfor your request. Please verify your tracking number and try again later.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM