Посмотрите на документацию / примеры пространств имен effbot; в частности, функция parse_map . В нем показано, как добавить атрибут * ns_map * к каждому элементу, который содержит префикс / сопоставление URI, которое применяется к этому конкретному элементу.
Однако, это добавляет атрибут ns_map ко всем элементам. Для своих нужд я обнаружил, что мне нужна глобальная карта всех пространств имен, используемых для упрощения поиска элементов и их отсутствия.
Вот что я придумал:
import elementtree.ElementTree as ET
def parse_and_get_ns(file):
events = "start", "start-ns"
root = None
ns = {}
for event, elem in ET.iterparse(file, events):
if event == "start-ns":
if elem[0] in ns and ns[elem[0]] != elem[1]:
# NOTE: It is perfectly valid to have the same prefix refer
# to different URI namespaces in different parts of the
# document. This exception serves as a reminder that this
# solution is not robust. Use at your own peril.
raise KeyError("Duplicate prefix with different URI found.")
ns[elem[0]] = "{%s}" % elem[1]
elif event == "start":
if root is None:
root = elem
return ET.ElementTree(root), ns
При этом вы можете анализировать xml-файл и получать dict с отображениями пространства имен. Итак, если у вас есть XML-файл, подобный следующему («my.xml»):
<?xml version="1.0" encoding="UTF-8" ?>
<rss version="2.0"
xmlns:content="http://purl.org/rss/1.0/modules/content/"
xmlns:dc="http://purl.org/dc/elements/1.1/"\
>
<feed>
<item>
<title>Foo</title>
<dc:creator>Joe McGroin</dc:creator>
<description>etc...</description>
</item>
</feed>
</rss>
Вы сможете использовать пространства имен xml и получать информацию для таких элементов, как dc: creator :
>>> tree, ns = parse_and_get_ns("my.xml")
>>> ns
{u'content': '{http://purl.org/rss/1.0/modules/content/}',
u'dc': '{http://purl.org/dc/elements/1.1/}'}
>>> item = tree.find("/feed/item")
>>> item.findtext(ns['dc']+"creator")
'Joe McGroin'