python: Gibt es einen XML-Parser, der als Generator implementiert ist?

8

Ich möchte eine große XML-Datei "on the fly" analysieren. Ich würde gerne einen Python-Generator verwenden, um dies durchzuführen. Ich habe "iterparse" von "xml.etree.cElementTree" ausprobiert (was wirklich nett ist), aber immer noch kein Generator.

Andere Vorschläge?

    
jldupont 03.10.2009, 12:14
quelle

4 Antworten

6

"On the Fly" Parsing- und Dokumentbäume sind nicht wirklich kompatibel. Hierfür werden normalerweise SAX-artige Parser verwendet (zum Beispiel Pythons Standard xml.sax ). Sie müssen im Grunde eine Klasse mit Handlern für verschiedene Ereignisse wie startElement, endElement usw. definieren, und der Parser wird die Methoden beim Analysieren der XML-Datei aufrufen.

    
Lukáš Lalinský 03.10.2009, 12:20
quelle
15

xml.etree.cElementTree kommt bei korrekter Verwendung einem Generator nahe; Standardmäßig erhalten Sie jedes Element nach seinem Ereignis 'end', an dem Sie es verarbeiten können. Sie sollten element.clear () für das Element verwenden, wenn Sie es nach der Verarbeitung nicht benötigen. Dadurch speichern Sie den Speicher.

Hier ist ein komplettes Beispiel, was ich meine, wo ich Rhythmbox (Music Player) Library parse. Ich benutze (c) ElementTree's iterparse und für jedes verarbeitete Element rufe ich element.clear () auf, damit ich ziemlich viel Speicher speichere. (Btw, der folgende Code ist ein Nachfolger für einen Sax-Code, um das Gleiche zu tun; die cElementTree-Lösung war eine Erleichterung seit 1) Der Code ist prägnant und drückt aus, was ich brauche und nichts mehr 2) Es ist 3x so schnell, 3) es verwendet weniger Speicher.)

%Vor%

Nun, ich verstehe Ihre Erwartungen nicht, haben Sie die folgende Erwartung?

%Vor%

Bei jedem Aufruf von iterparse erhalten Sie ein neues Iterator-Objekt und lesen die Datei neu! Wenn Sie ein persistentes Objekt mit Iterator-Semantik wünschen, müssen Sie in beiden Schleifen auf das gleiche Objekt verweisen (unversuchter Code):

%Vor%

Ich denke, es kann verwirrend sein, da verschiedene Objekte unterschiedliche Semantiken haben. Ein Dateiobjekt wird immer einen internen Status haben und in der Datei weiterkommen, jedoch iterieren Sie darauf. Ein ElementTree-Itersparse-Objekt anscheinend nicht. Der Kernpunkt ist zu denken, dass, wenn Sie eine for-Schleife verwenden, das for immer iter () auf dem Ding aufruft, über das Sie iterieren. Hier ist ein Experiment, das ElementTree.iterparse mit einem Dateiobjekt vergleicht:

%Vor%

Sie sehen, dass jeder Aufruf von iter () für ein Iterparse-Objekt einen neuen Generator zurückgibt. Das Dateiobjekt hat jedoch einen internen Betriebssystemzustand, der konserviert werden muss, und es ist ein eigener Iterator.

    
u0b34a0f6ae 03.10.2009 12:40
quelle
4

PullDom erledigt, was Sie wollen. Es liest XML aus einem Stream wie SAX, baut dann aber ein DOM für ein ausgewähltes Teil davon auf.

"PullDOM ist eine wirklich einfache API für die Arbeit mit DOM-Objekten in einer Streaming-Methode (effizient!) und nicht als monolithische Struktur."

    
RichieHindle 03.10.2009 12:30
quelle
0

Dies ist mit elementtree und incremental parsing möglich: Ссылка

%Vor%

Einfacher zu verwenden als Sax.

    
hoju 01.01.2012 14:10
quelle

Tags und Links