2009-08-08 4 views
18

Per impostazione predefinita, quando si chiama ElementTree.parse (someXMLfile) i prefissi libreria Python elementtree ogni nodo analizzato con esso di namespace URI in notazione di Clark:Alter spazio dei nomi anteponendo ElementTree in Python

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

Questo rende l'accesso nodi specifici per nome un enorme dolore più avanti nel codice.

Ho letto i documenti su ElementTree e namespace e sembra che la funzione iterparse() mi consenta di modificare il modo in cui il parser prefissa i namespace, ma per la vita di me non riesco a farlo cambiare il prefisso . Sembra che possono accadere in background prima che l'evento ns-start anche incendi come in questo esempio:

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

Come faccio a farlo modificare il comportamento prefisso di e qual è la cosa giusta per tornare quando finisce di funzione ?

+1

interessante. Mi piacerebbe saperlo anche io. Il mio modo di procedere consiste nel creare "costante" XHTML_NS = '{http://www.w3.org/1999/xhtml}' e quindi utilizzare nel codice XHTML_NS + "mynode" – karlcow

+0

Puoi spiegare cosa stai effettivamente cercando di ottenere ? Perché la notazione di Clark è un dolore enorme? –

+0

Sto cercando di integrare con il codice esistente che accede alle cose con il loro prefisso originale (cioè 'openSearch', piuttosto che' {http://a9.com/-/spec/opensearchrss/1.0/} ') e speravo c'era un modo più carino di costruire il tipo di mappa dei prefissi che @karlcow menziona. –

risposta

6

Non è specificamente necessario utilizzare iterparse. Al contrario, il seguente 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 = '''<?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) 

che mostra come è possibile accedere ai nomi dei tag completo del singoli nodi in un albero analizzata. Dovresti essere in grado di adattarlo alle tue esigenze specifiche.

2

xml.etree.ElementTree non sembra avere il fixtag, beh, non secondo la documentazione. Tuttavia Ho guardato un po 'di codice sorgente per fixtag e si fa:

import xml.etree.ElementTree as ET 

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

avete la stringa di tag in looktag, adatto per una ricerca. Lo spazio dei nomi è nello spazio dei nomi.

+3

Nel mio Python 2.6.5, xml.etree.ElementTree ha una funzione fixtag, ma xml.etree.cElementTree no. –