Regardez la documentation/les exemples des espaces de noms effbot; spécifiquement la fonction parse_map. Il vous montre comment ajouter un attribut * ns_map * à chaque élément qui contient le mappage préfixe/URI qui s'applique à cet élément spécifique.
Toutefois, cela ajoute l'attribut ns_map à tous les éléments. Pour mes besoins, j'ai trouvé que je voulais une carte globale de tous les espaces de noms utilisés pour que l'élément recherche plus facilement et non codé en dur.
Voici ce que je suis venu avec:
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
Avec cela, vous pouvez analyser un fichier xml et obtenir un dict avec les applications d'espace de noms. Donc, si vous avez un fichier xml comme ce qui suit ("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>
Vous serez en mesure d'utiliser les namepaces xml et obtenir des informations pour des éléments comme 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'
Je ne peux pas répondre à votre question - mais après avoir lutté contre cette lacune pendant quelques jours, je suis prêt à affirmer que ce n'est pas possible avec l'API ElementTree actuelle. Dans mon application, j'avais besoin de détecter si un attribut xmlns: xlink existait déjà sur l'élément racine, et sinon, ajoutez-le. Il n'est pas possible de tester si un attribut xmlns existe déjà et quoi de plus, ElementTree est heureux de l'ajouter deux fois si vous essayez. Comme zéro ou deux attributs xmlns identiques dans le même élément provoquent une erreur dans la plupart des utilisateurs XML, cela rend très difficile l'utilisation d'ElementTree. –