Seite 1 von 1
große XML häppchenweise einlesen
Verfasst: Montag 31. März 2008, 12:45
von droptix
Kann man mit Python eine große XML-Datei häppchenweise einlesen? Ich denke mir sowas:
Code: Alles auswählen
<?xml version="1.0"?>
<root>
<meta>
<!-- small data -->
</meta>
<info>
<!-- small data -->
</info>
<content>
<!-- BIG data -->
</content>
</root>
Ich brauche aus dem XML nur die Elemente <meta> und <info>, nicht aber den Rest. Kann man recht zügig und ohne die gesamte XML-Datei einlesen zu müssen nur die ersten Elemente einlesen?
Verfasst: Montag 31. März 2008, 13:21
von BlackJack
Mit einem SAX-Parser nur <meta> und <info> verarbeiten, bzw. `ElementTree.iterparse()` verwenden.
Verfasst: Montag 31. März 2008, 13:37
von droptix
Welchen Parser verwendet Python standardmäßig? Ich dachte das wäre Expat... Da ich gern was plattformübergreifendes hätte, klingt die `ElementTree`-Geschichte erstmal gut. Wie löst denn `ElementTree.iterparse()` das Problem? Wird nicht trotzdem erstmal die gesamte Datei eingelesen?
Verfasst: Montag 31. März 2008, 17:12
von Leonidas
droptix hat geschrieben:Welchen Parser verwendet Python standardmäßig? Ich dachte das wäre Expat... Da ich gern was plattformübergreifendes hätte
Und Expat ist etwa nicht platformunabhängig? Wenn du SAX nutzt, kann dir der Parser mehr oder weniger egal sein, SAX ist sowieso überall gleich (unangenehm).
Verfasst: Dienstag 1. April 2008, 10:09
von droptix
Leonidas hat geschrieben:Und Expat ist etwa nicht platformunabhängig? Wenn du SAX nutzt, kann dir der Parser mehr oder weniger egal sein, SAX ist sowieso überall gleich (unangenehm).
Klar ist Expat plattformabhängig, aber ich dachte in Python "
eingebaut". Hab das so verstanden, dass Python für SAX nur eine
Schnittstelle bietet. Aber ich gebe zu, dass es etwas unübersichtlich ist…
Wer weiß mehr? Kommen Expat bzw. SAX mit Python mit?
Verfasst: Dienstag 1. April 2008, 10:31
von audax
Schau in die Doku. python.org/doc
Da steht das alles, wirklich!
Verfasst: Dienstag 1. April 2008, 10:53
von droptix
xml.parsers.expat hat geschrieben:The xml.parsers.expat module is a Python interface to the Expat non-validating XML parser. […] This module uses the pyexpat module to provide access to the Expat parser.
D.h. das
pyexpat Modul muss separat installiert werden (es wird nicht im Global Module Index aufgelistet)?
xml.sax hat geschrieben:The xml.sax package provides a number of modules which implement the Simple API for XML (SAX) interface for Python. The package itself provides the SAX exceptions and the convenience functions which will be most used by users of the SAX API.
SAX kenne ich nur in Verbindung mit fertigen SAX-Parsern. Frage: liefert Python einen mit? Oder ist das
xml.sax Modul bereits alles, was ich benötige?
Verfasst: Dienstag 1. April 2008, 12:11
von BlackJack
Ja Python liefert einen SAX-Parser.
Verfasst: Dienstag 1. April 2008, 14:19
von droptix
Von Haus aus für jede Plattform oder muss da ein Extra-Modul installiert werden?
Mit TkInter ist das ja ähnlich: unter Windows ist das von Haus aus dabei, unter Linux muss das aber u.U. erst nachinstalliert werden, aber es gehört wenigstens zur Standard-Distribution. Daher meine Unsicherheit...
Verfasst: Dienstag 1. April 2008, 14:30
von Leonidas
droptix hat geschrieben:Leonidas hat geschrieben:Und Expat ist etwa nicht platformunabhängig? Wenn du SAX nutzt, kann dir der Parser mehr oder weniger egal sein, SAX ist sowieso überall gleich (unangenehm).
Klar ist Expat plattformabhängig, aber ich dachte in Python "
eingebaut". Hab das so verstanden, dass Python für SAX nur eine
Schnittstelle bietet. Aber ich gebe zu, dass es etwas unübersichtlich ist…
Ist es doch. Alles was im Global Module Index dukumentiert ist, ist in der Stdlib. Ich sehe dein Problem nicht.
Expat kannst du zwar direkt nutzen, aber du kannst genauso gut auch die "höheren" APIs SAX und Minidom oder ElementTree verwenden (ich würde ja zu ET, aber mindestens zu DOM raten, weil SAX echt PITA ist). Wenn es schnell gehen soll, dann ist sowieso lxml die erste Wahl, wie der aktuelle Geschwindigkeitsvergleich von Ian Bicking zeigte.
Und wie das Python-Paket auf Linux aufgeteilt wird, ist nicht definiert. Die Distributionen können das Paket splitten wie sie wollen, sie können auch Teile (etwa den Profiler) weglassen. Aber es macht keinen sinn, wegen solchen Überlegungen auf einen Parser in der Stdlib zu verzichten. Unter Windows kann ich auch entscheiden Tkinter nicht zu installieren, also ist es nicht von Haus aus dabei.
Verfasst: Dienstag 1. April 2008, 17:40
von BlackJack
@Leonidas: Das XML soll nicht ganz verarbeitet werden, sondern nur ein verhältnismässig kleiner Teil am Anfang. Damit fällt DOM im Grunde raus.
Verfasst: Dienstag 1. April 2008, 18:31
von Leonidas
BlackJack hat geschrieben:@Leonidas: Das XML soll nicht ganz verarbeitet werden, sondern nur ein verhältnismässig kleiner Teil am Anfang. Damit fällt DOM im Grunde raus.
Hmm, wieso? Solange das XML-Dokument nicht zu groß ist, kann man es doch problemlos einlesen. Wenn es tatsächlich zu langsam wird, kann man sich immer noch was überlegen. Es ist schon möglich, dass hier ein Fall von Premature Optimization vorliegt. Ist DOM tatsächlich ein Performance-Problem oder nur ein geschätztes Problem?
Verfasst: Dienstag 1. April 2008, 19:49
von BlackJack
Ich bin halt davon ausgegangen, dass der Kommentar in Zeile 10 im ersten Beitrag ernst gemeint war.
Verfasst: Dienstag 1. April 2008, 20:02
von Leonidas
BlackJack hat geschrieben:Ich bin halt davon ausgegangen, dass der Kommentar in Zeile 10 im ersten Beitrag ernst gemeint war.
BIG data kann ja alles mögliche meinen. Es kann ja immer noch klein genug sein, so dass man es mit dem kompletten Parsen angehen kann. Sowas muss man eben ausprobieren. Bevor ich zu SAX greifen würde, tät ich wirklich erst nachsehen ob es wirklich ein ausreichend großes Problem ist.
Verfasst: Dienstag 1. April 2008, 21:50
von droptix
Na, gehen wir mal davon aus, dass in <!-- BIG data --> wirklich zu große Daten stehen, also nehmen wir ruhig 10.000 bis 50.000 Zeilen an.
Verfasst: Dienstag 1. April 2008, 21:58
von Leonidas
droptix hat geschrieben:Na, gehen wir mal davon aus, dass in <!-- BIG data --> wirklich zu große Daten stehen, also nehmen wir ruhig 10.000 bis 50.000 Zeilen an.
Und, ist es mit Minidom zu langsam für dich?
Verfasst: Dienstag 1. April 2008, 22:05
von droptix
Nun ja, die Geschwindigkeit hab ich noch gar nicht gemessen, nur gefühlt dauert das schon sehr lange. Aber den Speicherverbrauch hab ich gemessen, und der explodiert mit minidom gewaltig. Eine XML-Datei mit gut 20.000 Zeichen ist so um die 1,5 MB groß. Beim Einlesen werden ca. 90 MB Arbeitsspeicher benötigt. Das ist recht heftig.
Verfasst: Dienstag 1. April 2008, 22:27
von Leonidas
Ok, das ist nun endlich mal etwas handfestes. Also kannst du mal das mit SAX implementieren und gucken, wie es im Vergleich dazu abschneidet.
Verfasst: Donnerstag 3. April 2008, 08:22
von rezeptor
Ich würde zu ElementTree greifen. Das Modul benutzt ja wie bereits gesagt Expat und da dieser stream-orientiert arbeitet, kannst du dir ElementTree ableiten und in die Feed-Methode entsprechende Funktionalitäten zur steuerung der zu parsenden Datenmenge einbauen. (Also bevor du den eigentlichen Feed-Call zur Basisklasse machst.)
Verfasst: Montag 7. April 2008, 22:21
von nkoehring
@rezeptor: Hmm... das klingt ja nett, aber wie soll man das denn anstellen? Haettest du da ein kurzes Beispiel?