2009-08-08 33 views
18

Por defecto, cuando se llama ElementTree.parse (someXMLfile) los prefijos biblioteca de Python elementtree cada nodo analizado con ella es URI de espacio en la notación de Clark:Alter espacio de nombres prefijar con elementtree en Python

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

Esto hace que el acceso a nodos específicos por nombre un gran dolor 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 alterar la forma en que el analizador prefija espacios de nombres, pero durante mi vida no puedo cambiar el prefijo . Parece que puede suceder en el fondo antes del evento ns-inicio incluso incendios 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 prefijar y qué es lo más apropiado para volver cuando termina la función ?

+1

interesante. Me gustaría saber también. La forma en que procedo es creando "constante" XHTML_NS = '{http://www.w3.org/1999/xhtml}' y luego usando en el código XHTML_NS + "mynode" – karlcow

+0

¿Puede explicar lo que realmente está tratando de lograr? ? ¿Por qué la notación de Clark es un gran dolor? –

+0

Estoy tratando de integrar con el código existente que accede a las cosas por su prefijo original (es decir, 'openSearch', en lugar de' {http://a9.com/-/spec/opensearchrss/1.0/} ') y estaba esperando había una manera más agradable que construir el tipo de mapa de prefijo que menciona @karlcow. –

Respuesta

6

No necesita usar específicamente iterparse. En su lugar, la secuencia de comandos siguiente:

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 = '''<?xml version="1.0" encoding="utf-8"?> 
<rdc:container xmlns:mx="http://www.adobe.com/2006/mxml" 
       xmlns:rdc="http://www.red-dove.com/ns/abc" 
       xmlns:oth="http://www.red-dove.com/ns/def"> 
    <mx:Style> 
    <oth:style1/> 
    </mx:Style> 
    <mx:Style> 
    <oth:style2/> 
    </mx:Style> 
    <mx:Style> 
    <oth:style3/> 
    </mx:Style> 
</rdc:container>''' 

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:Style', None) 
('oth:style2', None) 

que muestra cómo se puede acceder a los nombres de las etiquetas totalmente calificados de los nodos individuales en un árbol analizada. Debería poder adaptar esto a sus necesidades específicas.

2

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

import xml.etree.ElementTree as ET 

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

Usted tiene la cadena de etiqueta en looktag, adecuado para una búsqueda. El espacio de nombres está en el espacio de nombres.

+3

En mi Python 2.6.5, xml.etree.ElementTree tiene una función de etiqueta de identificación, pero xml.etree.cElementTree no. –

Cuestiones relacionadas