quant
quant

Reputation: 23172

How do I access elements in an XML when multiple default namespaces are used?

I would expect this code to produce a non-empty list:

import xml.etree.ElementTree as et

xml = '''<?xml version="1.0" encoding="UTF-8"?>
<A
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns="a:namespace">
    <B xmlns="b:namespace">
        <C>"Stuff"</C>
    </B>
</A>
'''
namespaces = {'a' : 'a:namespace', 'b' : 'b:namespace'}
xroot = et.fromstring(xml)

res = xroot.findall('b:C', namespaces)

instead, res is an empty array. Why?

When I inspect the contents of xroot I can see that the C item is within b:namespace as expected:

for x in xroot.iter():
    print(x)

# result:
<Element '{a:namespace}A' at 0x7f56e13b95e8>
<Element '{b:namespace}B' at 0x7f56e188d2c8>
<Element '{b:namespace}C' at 0x7f56e188def8>

To check whether something was wrong with my namespacing, I tried this as well; xroot.findall('{b:namespace}C') but the result was an empty array as well.

Upvotes: 0

Views: 142

Answers (1)

Your findall xpath 'b:C' is searching only tags immediately in the root element; you need to make it './/b:C' so the tag is found anywhere in the tree and it works, e.g.:

import xml.etree.ElementTree as et

xml = '''<?xml version="1.0" encoding="UTF-8"?>
<A
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns="a:namespace">
    <B xmlns="b:namespace">
        <C>"Stuff"</C>
    </B>
</A>
'''
namespaces = {'a' : 'a:namespace', 'b' : 'b:namespace'}
xroot = et.fromstring(xml)

######## changed the xpath to start with .//
res = xroot.findall('.//b:C', namespaces)

print( f"{res=}" )

for x in xroot.iter():
    print(x)

Output:

res=[<Element '{b:namespace}C' at 0x00000222DFCAAA40>]
<Element '{a:namespace}A' at 0x00000222DFCAA9A0>
<Element '{b:namespace}B' at 0x00000222DFCAA9F0>
<Element '{b:namespace}C' at 0x00000222DFCAAA40>

See here for some useful examples of ElementTree xpath support https://docs.python.org/3/library/xml.etree.elementtree.html?highlight=xpath#xpath-support

Upvotes: 1

Related Questions