[PHP] gigantische XML verarbeiten

wahnsinn

Teilzeitcholeriker
ID: 13929
L
20 April 2006
1.168
152
Grüßt euch,

ich muss für ein Projekt eine riesige XML-Datei einlesen, die enthaltenen Daten auswerten/umwandeln und anschließend in eine MySQL-Tabelle schreiben.

Leider ist die XML-Datei ca. 70 MB groß und lässt sich in keinem Programm außer Notepad halbwegs vernünftig öffnen. Ich weiß also noch nicht einmal, wie viele Datensätze enthalten sind. Erschwerend kommt noch hinzu, dass der Spaß ungefähr jeden Monat neu importiert werden muss, um ggf. Änderungen zu erkennen und Updates zu machen. Hat jemand einen Vorschlag, wie ich das Teil halbwegs praktikabel in die Datenbank bringe?

Die Datei einlesen, in ein Array umwandeln und dann das Array nach und nach abarbeiten würde wahrscheinlich funktionieren, dauert aber ewig und belastet den Server bestimmt ziemlich.

Jedenfalls bräuchte ich eine Lösung, die mit PHP4 funktioniert. Hat jemand Ideen oder Gedankenanstöße?
 
Mit php kannst du es machen, einfach über die komandozeile. Dann ist es egal wie lange es dauert.
Dann importierst du einfach den SQL Dump mit dem phpmyadmin oder wie auch immer und du hast du dateien...


Mfg
Wusel
 
neija der interne aufbau der xml wäre schon interessant, wenn er nicht zu kompliziert ist könnte man mit regulären ausdrücken und nen fget() bufferweise einlesen
 
Da nimmst du einfach expat von PHP, ist zwar ein wenig gewöhnungsbedürftig, aber das kann auch mit großen Datei gut umgehen.
 
fget() bufferweise einlesen
Liest das nicht alles Zeilenweise aus? Leider steht das ganze XML-Gedöns in einer einzigen Zeile. :doh:

Da nimmst du einfach expat von PHP, ist zwar ein wenig gewöhnungsbedürftig, aber das kann auch mit großen Datei gut umgehen.
expat? Hmmm ... mal schauen ob ich damit klar komm.


//edit:
Das mit expat scheint mir doch ein bisschen kompliziert für mein Niveau. :-?


// edit2:
Ich hab mich doch an expat rangewagt. Klappt wunderbar. Vielen Dank.
 
Zuletzt bearbeitet:
Also es klappt mit expat jetzt soweit sehr gut. Vielen Dank nochmal für den Tipp.

Allerdings habe ich jetzt ein anderes kleines Problem. Die Helden, die die XML produziert haben, haben keine Kennzeichnungen mit <![CDATA[ ... ]]> vorgenommen und expat kommt jetzt wenn ein & im Content vorkommt, ziemlich durcheinander.

Hat da jemand einen Tipp, wie ich dem abhelfen kann?
 
hm, kannst du diese datei-ersteller nicht einfach diesen hinweis geben? immerhin ist es für dich wichtig.

du könntest ansonsten die datei zuvor preparieren. also in einem vorgeschalteten prozess gestückelt einlesen und problembereiche versuchen zu elimenieren. per regex könntest du das in der bereits vorgeschlagenen buffer-variante versuchen.
 
Ok, bis jetzt ist alles gelöst. Allerdings stehe ich nun schon wieder vor einem Problem.

Irgendwie klappt das mit dem Einlesen der Werte nicht so toll. Eine gewisse Anzahl von Ausgelesenen Strings sind immer abgeschnitten. Es kommt also z.B. statt Löwenzahn nur öwenzahn an. Ich kann das aber nicht bei über 14000 Einträgen alles manuell überprüfen und ggf. korrigieren.

Hier der Code-Abschnitt, bei dem ich die Schuldigkeit vermute.

PHP:
while ($data = fread($fp, 4096)) {
	if (!xml_parse($this->xml_parser, $data, feof($fp))) {
		die(sprintf("XML error: %s at line %d",
		            xml_error_string(xml_get_error_code($this->xml_parser)),
		            xml_get_current_line_number($this->xml_parser)));
	}
}

Zum Test habe ich mal den Wert 4096 durch einen anderen Wert ersetzt. Bei 1024 waren scheinbar viel mehr Felder falsch übergeben, während ich bei einem Versuch mit 4096*8 keine Unterschiede zu 4096 feststellen konnte.