Mire la documentación/ejemplos de los espacios de nombres de effbot; específicamente la función parse_map. Le muestra cómo agregar un atributo * ns_map * a cada elemento que contiene el mapeo de prefijo/URI que se aplica a ese elemento específico.
Sin embargo, eso agrega el atributo ns_map a todos los elementos. Para mis necesidades, descubrí que quería un mapa global de todos los espacios de nombres utilizados para hacer que la búsqueda de elementos fuera más fácil y no codificada.
Esto es lo que ocurrió:
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
Con esto se puede analizar un archivo XML y obtener un diccionario con las asignaciones de espacio de nombres. Por lo tanto, si usted tiene un archivo XML como el siguiente ("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>
usted será capaz de utilizar las namepaces XML y obtener información para elementos como 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'
No puedo responder a su pregunta, pero después de haber luchado contra esta deficiencia durante un par de días, estoy dispuesto a afirmar que no es posible utilizarla con la API actual de ElementTree. En mi aplicación, necesitaba detectar si ya existía un atributo xmlns: xlink en el elemento raíz, y si no, agregarlo. No es posible probar si ya existe un atributo xmlns y, lo que es más, ElementTree se complace en agregarlo dos veces si lo intentas. Dado que cero o dos atributos xmlns idénticos en el mismo elemento causan un error en la mayoría de los consumidores XML, esto hace que ElementTree sea muy difícil de usar. –