Python comparing XML output to a list
Question: I have an XML that looks something like this:

    
    
    <Import>
      <spId>1234</spId>
      <GroupFlag>false</GroupFlag>
    </Import>
    

I want to extract the value of spId and compare it with a list and I have the
following script:

    
    
    import xml.etree.ElementTree as ET
    xml_file = "c:/somefile.xml"
    
    sp_id_list = ['1234']
    tree = ET.parse(xml_file)
    root = tree.getroot()
    
    for sp_id in root.findall('./spId'):
      if sp_id.text in sp_id_list:
        print sp_id.text
    

This doesn't work for spId (numeric) but works for comparing GroupFlag
(string) with a list. Why is this happening and how can I rectify this
problem?

Sorry for the stupid question, I am a noob to this.


Answer: Your code example works correctly if your XML sample posted here is given as
input XML file.

However you want to find all elements. So, I assume that your real document
has many `<Import>` items. If a list of items is not wrapped by some parent
tag it is not a valid XML. In that case you would have
`xml.etree.ElementTree.ParseError`.

So, I assume that in your real document `<Import>` is not a root element and
`<Import>` elements are somewhere deeper in the document, for example

    
    
    <Parent>
      <Import>
        <spId>1234</spId>
        <GroupFlag>false</GroupFlag>
      </Import>
      <Import>
        <spId>1234</spId>
        <GroupFlag>false</GroupFlag>
      </Import>
    </Parent>
    

In that case the search pattern `'./spId'` cannot find those tags, since that
pattern matches only direct children of the root element. So, you can use
[XPath](https://docs.python.org/2/library/xml.etree.elementtree.html#elementtree-
xpath) matching tags all levels beneath or even better pointing direct path
from the root to the level where `spId` is located:

    
    
    # all subelements, on all levels beneath the current element
    root.findall('.//spId')
    
    # all spId elements directly in Import tags that are directly
    # beneath the root element (as in the above XML example)
    root.findall('./Import/spId'):
    

