Seite 1 von 1

Sehr große XML Datei auf dem Server verarbeiten

Verfasst: 29.07.2007, 19:11
von nachfrag
Hallo,

ich googel schon seit einer Weile und komme bei meinem Problem auf keinen grünen Zweig:
Es sollen täglich automatisiert auf dem Webserver sehr große XML Dateien eingelesen und verarbeitet werden (die Dateien können bis ein paar hundert MB groß werden). Wie erwartet macht PHP beim Einlesen so großer Dateien schlapp wegen nicht genug Arbeitsspeicher.
Ich habe es versucht mit simpleXML Funktionen und
https://www.media-palette.de/tools/xml-line aber die Datei ist zu groß.
Bei CSV Dateien war dies nie ein Problem, die kann man mit einem shell Skript "spilt"-ten und dann abarbeiten - aber das XML kann ich ja nicht einfach nach 1000 Zeilen abschneiden ...
Mein Denkansatz (bei dem ich nicht so ganz weiterkomme) ist, dass es ohne Aufteilen der XML Dateien wohl nicht gehen wird, aber wie mache ich das am besten?

Wäre sehr dankbar für Denkanstöße oder konkrete Tipps!

Grüße

Verfasst:
von
SEO Consulting bei ABAKUS Internet Marketing
Erfahrung seit 2002
  • persönliche Betreuung
  • individuelle Beratung
  • kompetente Umsetzung

Jetzt anfragen: 0511 / 300325-0.


Alles in eine mysql lesen, dann verabreiten und ausgeben

Verfasst: 29.07.2007, 20:01
von seonewbie
Hallo,

hatte neulich ein ähnliches Problem und habe alles
verworfen ...

Ich lese nun in eine mysql Datenbank verarbeite und
schiebe wieder raus. Alles andere hat sich inder Praxis
zu Fehlerbehaftet erwiesen. Insbesondere kannst
du bei mysql Fehler besser "Behandeln" ohne das das
script abgebrochen wird.

Gruß

Micha

Verfasst: 29.07.2007, 20:47
von net(t)worker
muss das script zur verarbeitung per browser gestartet werden, oder würde es auch über shellaufruf funktionieren? Beim Aufruf über Shell könnte man dem script wesentlich mehr Speicher geben indem man per parameter die Speicherzuteilung in der php.ini überschreibt...

Verfasst: 29.07.2007, 22:12
von nachfrag
@net(t)worker:
ja das Skript wird per shell aufgerufen.
Speicherzuteilung per Parameter überschreiben - kannst du das erklären?

Grüße

edit:

@seonewbie: Ich kann mir die Datenquelle leider nicht aussuchen ;) - im Endeffekt sollen die Daten in eine MySQL ...

Verfasst: 30.07.2007, 01:02
von net(t)worker
/Pfad/zu/php -d memory_limit=128M /pfad/zu/script.php


setzt z.B. das memory Limit für die Ausführung des scriptes auf 128MB.... mit

-d php.ini-Option=Wert

kann man die Angaben in der php.ini überschreiben... und da das script ja immer nur einmalig aufgerufen wird, kann man hier den Speicher ruhig etwas großzügiger zuweisen... man muss das script ja auch nicht unbedingt zur "Hauptverkehrszeit" aufrufen... :wink:

Verfasst: 30.07.2007, 08:32
von nachfrag
Scheint zu klappen, super!
Vielen Dank!!!
Das war der entscheidende Anstoß den ich brauchte :)
(dachte eine Lösung wäre viieel komplizierter ;) ...)

Grüße

Verfasst: 31.07.2007, 12:42
von dpahl
Scheinbar ist die passende Lösung gefunden, aber ich hatte auch schonmal einen Fall, wo das nicht ausgereicht hat. Lösung war folgende:

Hab ein Perl-Script split.pl geschrieben, um den Wikipedia-XML-Dump in kleinere Stücke aufzuteilen:

Code: Alles auswählen


#!/usr/bin/perl

$count = 0;
$filecount = 0;
$splitsize = 250000;
$infofound = 0;

open(DATEI, ">/var/www/wiki$filecount.xml");

while&#40;$line=<STDIN>&#41; 
&#123;
    #$line =~ s/\s+|\t+//g;
    
    if&#40;$line =~ /<\/siteinfo>/&#41;
    &#123;
	push&#40;@TitelZeilen,$line&#41;;
	$infofound = 1;
    &#125;
    
    if&#40;$infofound == 0&#41;
    &#123;
	push&#40;@TitelZeilen,$line&#41;;
    &#125;
    
    if&#40;$line =~ /<\/page>/&#41;
    &#123;
	#print "$count <br>\n";
	print DATEI $line;
	
	if&#40;$count == $splitsize&#41;
	&#123;
	    $filecount++;
	    $count = 0;
	    print DATEI "</mediawiki>";
	    close&#40;DATEI&#41;;
	    open&#40;DATEI, ">/var/www/wiki$filecount.xml"&#41;;
	    print DATEI @TitelZeilen;
	&#125;
	
	#my @array = split&#40;/\W/, $line&#41;;
	#print "$array&#91;2&#93;\n";
	$count ++;
    &#125;
    else
    &#123;
	print DATEI $line;
    &#125;
&#125;

Die Originaldatei kann man dann so splitten:

cat wiki.xml | /var/www/split.pl