Alterar el prefijo de espacio de nombres con ElementTree en Python

De forma predeterminada, cuando llama a ElementTree.parse (algunos archivos XML), la biblioteca de Python ElementTree prefija cada nodo analizado con su URI de espacio de nombres en la Notación de Clark:

     {http://example.org/namespace/spec}mynode

Esto hace que el acceso a nodos específicos por nombre sea un gran problema más adelante en el código.

He leído los documentos en ElementTree y namespaces y parece que la función iterparse() debería permitirme modificar la forma en que el analizador prefiere los espacios de nombres, pero por mi vida no puedo hacer que cambie el prefijo. Parece que eso puede suceder en segundo plano antes de que el evento ns-start se dispare como en este ejemplo:

 for event, elem in iterparse(source): if event == "start-ns": namespaces.append(elem) elif event == "end-ns": namespaces.pop() else: ... 

¿Cómo puedo hacer que cambie el comportamiento de prefijo y qué es lo correcto para devolver cuando finaliza la función?

No necesitas utilizar iterparse . En cambio, el siguiente script:

 from cStringIO import StringIO import xml.etree.ElementTree as ET NS_MAP = { 'http://www.red-dove.com/ns/abc' : 'rdc', 'http://www.adobe.com/2006/mxml' : 'mx', 'http://www.red-dove.com/ns/def' : 'oth', } DATA = '''           ''' tree = ET.parse(StringIO(DATA)) some_node = tree.getroot().getchildren()[1] print ET.fixtag(some_node.tag, NS_MAP) some_node = some_node.getchildren()[0] print ET.fixtag(some_node.tag, NS_MAP) 

produce

 ('mx: Estilo', Ninguno)
 ('oth: style2', Ninguno)

Lo que muestra cómo puede acceder a los nombres de etiqueta completos de nodos individuales en un árbol analizado. Debería poder adaptar esto a sus necesidades específicas.

xml.etree.ElementTree no parece tener un fixtag, bueno, no de acuerdo con la documentación. Sin embargo, he mirado algún código fuente para fixtag y lo haces:

 import xml.etree.ElementTree as ET for event, elem in ET.iterparse(inFile, events=("start", "end")): namespace, looktag = string.split(elem.tag[1:], "}", 1) 

Tiene la cadena de tags en looktag, adecuada para una búsqueda. El espacio de nombres está en el espacio de nombres.