0

Here's something I don't get and hope someone can clarify for me.

With a simple XML tree, it's easy enough to get an attribute value from the first instance of a given element.

In [1]: import xml.etree.ElementTree as ET

In [2]: xml = """<?xml version="1.0" standalone="no"?>
   ...: <root>
   ...:     <level1>
   ...:         <level2
   ...:             id='abc'
   ...:             name='123'
   ...:         />
   ...:     </level1>
   ...: </root>"""

In [3]: root = ET.fromstring(xml)

In [4]: root.find('./level1/level2').attrib['id']
Out[4]: 'abc'

Now, if I add a namespace to the root, it doesn't work anymore, even with what I understand in the correct syntax:

In [6]: xml = """<?xml version="1.0" standalone="no"?>
   ...: <root xmlns="http://namespace.com">
   ...:     <level1>
   ...:         <level2
   ...:             id='abc'
   ...:             name='123'
   ...:         />
   ...:     </level1>
   ...: </root>"""

In [7]: root = ET.fromstring(xml)

In [8]: root.find('{http://namespace.com}./level1/level2').attrib['id']
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-8-2389d900412a> in <module>
----> 1 root.find('{http://namespace.com}./level1/level2').attrib['id']

AttributeError: 'NoneType' object has no attribute 'attrib'

Why is that, and what should I do instead?

mrgou
  • 1,576
  • 2
  • 21
  • 45
  • Been a long time since I've had to muck around with XML parsing, but ultimately you end up having to qualify the namespaces as they're not the default... so something like: `root.find('ns:level1/ns:level2', {'ns': 'http://namespace.com'}).attrib['id']` – Jon Clements Oct 09 '19 at 15:38
  • possible duplication : https://stackoverflow.com/questions/14853243/parsing-xml-with-namespace-in-python-via-elementtree – Charif DZ Oct 09 '19 at 15:42
  • No, it's not really the same (not even the same error). The namespace structure is different in the other question, so I don't know how I would apply the proposed solution. – mrgou Oct 09 '19 at 15:57
  • 1
    The syntax in the expression in `find()` is not correct. This should work: `'.//{http://namespace.com}level2'`. – mzjn Oct 09 '19 at 16:30
  • @mzjn, yes, that's it! I actually need to add the namespace to each element! Thank you!!! – mrgou Oct 09 '19 at 19:20
  • @JonClements, you may want to unmark this as a duplicate, since this is not the same question, nor the same error, nor, eventually, the same answer. – mrgou Oct 09 '19 at 19:21

0 Answers0