1

I'm trying to read parts of this XML, but don't understand why my xpath expressions are not matching anything.

s = """
<udhr iso639-3='ada' xml:lang='ada' key='ada' n='Dangme' dir='ltr' iso15924='Latn' xmlns="http://www.unhchr.ch/udhr">
   <title>JE TSUO BLƆ NYA TOMI KƐ HA ADESA HE BLƆHI</title>
   <preamble>
      <title>NYA TSƆƆMI</title>
      <para>Be abɔ nɛ a le odehe si himi nɛ Mawu bɔ adesahi tsuo nɛ a hi si ngɛ je mi, nɛ e ha nɔ tsuaa nɔ he blɔhi sɔsɔɛ, nɛ nɔ ko be he blɔ nɛ e kpɔɔ ngɛ a dɛ ɔ, e ji he jɔmi kɛ dami same yemi kɛ tue mi jɔmi a sipoku ngɛ je mi.</para>
    </preamble>
</udhr>
"""

import xml.etree.ElementTree as ET
tree = ET.fromstring(s)
print(list(tree))
# [<Element '{http://www.unhchr.ch/udhr}title' at 0x10dbf0050>, <Element '{http://www.unhchr.ch/udhr}preamble' at 0x10dbf0110>]
print(tree.findall("title"))
# []
print(tree.findall(".//preamble"))
# []

The elements are there, but applying any find xpath expressions come up empty. What obvious thing am I missing here?


So I've now found the namespace xmlns="http://www.unhchr.ch/udhr" declaration on the root, and when I use explicitly:

print(tree.findall("{http://www.unhchr.ch/udhr}title"))

It does find the element, but how do I use this namespace more generally? I've tried playing with the .findall(el, namespaces) dicts but cannot figure out how to get it working. After all my elements aren't prefixed?!

kontur
  • 4,934
  • 2
  • 36
  • 62
  • 2
    Use `print(tree.findall(".//{http://www.unhchr.ch/udhr}title"))` to get the two title elements. – E.Wiest Apr 15 '20 at 14:39
  • 2
    *After all my elements aren't prefixed?!* The root element of your XML has a default namespace, which implicitly places its descendents in that namespace. See duplicate links for how to deal with namespaces in XPath in general and in ElementTree in particular. – kjhughes Apr 15 '20 at 14:51
  • Thanks to both of you, I found this much myself by now ;) What I couldn't get to work is how to register the namespace so I could search without the prefix? I tried passing the `ns` parameter to `findall` but somehow I don't get how that object should "map". – kontur Apr 16 '20 at 15:05

0 Answers0