2009-08-08 9 views
18

Domyślnie, gdy dzwonisz ElementTree.parse (someXMLfile) przedrostków biblioteki Python ElementTree każdy analizowany węzeł z jego nazw URI w notacji Clarka:Brakuje nazw poprzedzania z ElementTree w Pythonie

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

To sprawia, że ​​dostęp do określonych węzłów z nazwy ogromny ból później w kodzie.

Przeczytałem dokumenty w ElementTree i przestrzeniach nazw i wygląda na to, że funkcja iterparse() powinna pozwolić mi zmienić sposób, w jaki parser przedrostkuje przestrzenie nazw, ale dla mojego życia nie mogę zmienić tego prefiksu . Wydaje się, że może się zdarzyć w tle przed zdarzeniem ns-start nawet pożarów jak w poniższym przykładzie:

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

Jak mogę zrobić to zmienić zachowanie poprzedzania i jaka jest właściwa rzecz do powrotu, gdy końce funkcyjnych ?

+1

interesujące. Chciałbym też wiedzieć. Postępuję w ten sposób, tworząc "stały" XHTML_NS = '{http://www.w3.org/1999/xhtml}', a następnie używając w kodzie XHTML_NS + "mynode" – karlcow

+0

Czy możesz wyjaśnić, co faktycznie próbujesz osiągnąć? ? Dlaczego notacja Clarka jest ogromnym bólem? –

+0

Próbuję zintegrować z istniejącym kodem, który uzyskuje dostęp do rzeczy przez ich pierwotny prefiks (np. 'OpenSearch', zamiast' {http://a9.com/-/spec/opensearchrss/1.0/} ') i miałem nadzieję był ładniejszy sposób niż budowanie typu mapy prefiksowej, o której wspomina @karlcow. –

Odpowiedz

6

Nie musisz specjalnie używać iterparse. Zamiast następujący scenariusz:

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) 

produkuje

 
('mx:Style', None) 
('oth:style2', None) 

który pokazuje w jaki sposób można uzyskać dostęp do w pełni kwalifikowanych nazw znaczników poszczególnych węzłów w sparsowaną drzewa. Powinieneś być w stanie dostosować to do swoich konkretnych potrzeb.

2

xml.etree.ElementTree wydaje się nie mieć fixtag, dobrze, nie zgodnie z dokumentacją. Jednak szukałem w pewnym kodzie źródłowym fixtag i zrobić:

import xml.etree.ElementTree as ET 

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

Masz ciąg tagu w looktag, korzystne dla odnośnika. Przestrzeń nazw znajduje się w przestrzeni nazw.

+3

W moim Pythonie 2.6.5, xml.etree.ElementTree ma funkcję fixtag, ale xml.etree.cElementTree nie. –

Powiązane problemy