Discussion:
XML speicherschonend analysieren
(zu alt für eine Antwort)
Stefan+ (Stefan Froehlich)
2022-06-07 09:04:01 UTC
Permalink
Ich habe ein paar Klassen, die unterschiedliche XML-Standards
erkennen (und in Abhängigkeit davon dann die passende
Weiterverarbeitung anstoßen, teilweise in PHP, teilweise extern).
Das läuft über DOMDocument und relativ simpel durch Abfrage der
obersten Elemente, Attribute u/o Namespaces.

Gerade eben ist mir einer dieser Jobs um die Ohren geflogen mit:

| Allowed memory size of 12582912000 bytes exhausted (tried to allocate 13801920612 bytes)

Für den konkreten Fall habe ich das Speicherlimit halt von 12
auf 15GB erhöht - aber es ist abzusehen, dass auch das über kurz
oder lang gesprengt werden wird, und irgendwann kommen dann
physikalische Grenzen.

Und jetzt? Von DOMDocument auf Stringverarbeitung umstellen, die
ersten paar kB einlesen und mit regulären Ausdrücken darauf
herumhacken? So unelegant war die Software schon einmal, dorthin
möchte ich nur ungern zurück.

Gibt es Alternativen, die auf XML-Dokumenten arbeiten können, ohne
das Dokument vollständig im Speicher halten zu müssen?

Servus,
Stefan
--
http://kontaktinser.at/ - die kostenlose Kontaktboerse fuer Oesterreich
Offizieller Erstbesucher(TM) von mmeike

Nur bezierpsen ist gehängter als küssen! Stefan: Für alte Gauner!
(Sloganizer)
Stefan+ (Stefan Froehlich)
2022-06-07 09:37:33 UTC
Permalink
Post by Stefan+ (Stefan Froehlich)
| Allowed memory size of 12582912000 bytes exhausted (tried to allocate 13801920612 bytes)
Für den konkreten Fall habe ich das Speicherlimit halt von 12 auf
15GB erhöht - aber es ist abzusehen, dass auch das über kurz oder
lang gesprengt werden wird, und irgendwann kommen dann
physikalische Grenzen.
Die nächste Grenze kam noch während des Absenden des letzten
Postings:

| DOMDocument::loadXML(): Input string is too long in [...]

Offenbar habe ich DOMDocument fertig durchgespielt :-(

Servus,
Stefan
--
http://kontaktinser.at/ - die kostenlose Kontaktboerse fuer Oesterreich
Offizieller Erstbesucher(TM) von mmeike

Schlimm bleibt schlimm: Stefan für alle Fälle!
(Sloganizer)
Karl Pflästerer
2022-06-07 10:19:59 UTC
Permalink
Post by Stefan+ (Stefan Froehlich)
Post by Stefan+ (Stefan Froehlich)
| Allowed memory size of 12582912000 bytes exhausted (tried to allocate 13801920612 bytes)
Für den konkreten Fall habe ich das Speicherlimit halt von 12 auf
15GB erhöht - aber es ist abzusehen, dass auch das über kurz oder
lang gesprengt werden wird, und irgendwann kommen dann
physikalische Grenzen.
Die nächste Grenze kam noch während des Absenden des letzten
| DOMDocument::loadXML(): Input string is too long in [...]
Offenbar habe ich DOMDocument fertig durchgespielt :-(
Muss es denn DOM sein? DOM hat das gesamte Dokument im Speicher.
Mit https://www.php.net/manual/en/class.xmlreader.php bearbeiten wir
auch sehr große XML Dokumente; diese Klasse ist deutlich
speicherschonender. Der Ansatz ist (IMHO) schöner als SAX. das wäre dann
mein nächster Vorschlag: https://www.php.net/manual/en/book.xml.php
Auch mit SAX kannst du nahezu beliebig große Dokumente verarbeiten.

KP
Stefan+ (Stefan Froehlich)
2022-06-07 11:16:50 UTC
Permalink
Post by Karl Pflästerer
Post by Stefan+ (Stefan Froehlich)
| DOMDocument::loadXML(): Input string is too long in [...]
Offenbar habe ich DOMDocument fertig durchgespielt :-(
Muss es denn DOM sein?
Müssen nicht, es ist vor allem eine Frage der Bequemlichkeit: Im
Lauf der Jahre habe ich die gesamte Infrastruktur darauf umgestellt,
das ist inzwischen ein wesentlicher Bestandteil einner
Klassenhierarchie zur Analyse weitgehend beliebiger Files.

Nützt aber nichts, wird sich ändern müssen.
Post by Karl Pflästerer
Mit https://www.php.net/manual/en/class.xmlreader.php bearbeiten
wir auch sehr große XML Dokumente; diese Klasse ist deutlich
speicherschonender. Der Ansatz ist (IMHO) schöner als SAX. das
https://www.php.net/manual/en/book.xml.php
Merci, da wird sich hoffentlich etwas machen lassen; ich brauche es
ja auch nur für die Formaterkennung, die Verarbeitung so großer
Files erfolgt dann eh durch eigene CLI-Programme, mit PHP würde das
ewig und ein Jahr dauern.

Servus,
Stefan
--
http://kontaktinser.at/ - die kostenlose Kontaktboerse fuer Oesterreich
Offizieller Erstbesucher(TM) von mmeike

Stefan - der frigidste Quatsch seit Menschengedenken.
(Sloganizer)
Stefan+ (Stefan Froehlich)
2022-06-09 10:26:03 UTC
Permalink
Post by Stefan+ (Stefan Froehlich)
Post by Karl Pflästerer
Mit https://www.php.net/manual/en/class.xmlreader.php bearbeiten
wir auch sehr große XML Dokumente; diese Klasse ist deutlich
speicherschonender. Der Ansatz ist (IMHO) schöner als SAX. das
https://www.php.net/manual/en/book.xml.php
Merci, da wird sich hoffentlich etwas machen lassen; ich brauche es
ja auch nur für die Formaterkennung, die Verarbeitung so großer
Files erfolgt dann eh durch eigene CLI-Programme, mit PHP würde das
ewig und ein Jahr dauern.
War dann gar nicht einmal so kompliziert, danke. Ein komplettes
Dokument möchte ich damit nicht parsen müssen, dafür ist es mir zu
rustikal; zur Formaterkennung reicht es aber ganz ausgezeichnet.

Servus,
Stefan
--
http://kontaktinser.at/ - die kostenlose Kontaktboerse fuer Oesterreich
Offizieller Erstbesucher(TM) von mmeike

Stefan. Da lacht der Hausmann!
(Sloganizer)
Karl Pflästerer
2022-06-10 08:50:55 UTC
Permalink
Post by Stefan+ (Stefan Froehlich)
Post by Stefan+ (Stefan Froehlich)
Post by Karl Pflästerer
Mit https://www.php.net/manual/en/class.xmlreader.php bearbeiten
wir auch sehr große XML Dokumente; diese Klasse ist deutlich
speicherschonender. Der Ansatz ist (IMHO) schöner als SAX. das
https://www.php.net/manual/en/book.xml.php
Merci, da wird sich hoffentlich etwas machen lassen; ich brauche es
ja auch nur für die Formaterkennung, die Verarbeitung so großer
Files erfolgt dann eh durch eigene CLI-Programme, mit PHP würde das
ewig und ein Jahr dauern.
War dann gar nicht einmal so kompliziert, danke. Ein komplettes
Dokument möchte ich damit nicht parsen müssen, dafür ist es mir zu
rustikal; zur Formaterkennung reicht es aber ganz ausgezeichnet.
Da sieht man, wie sich die Geschmäcker unterscheiden. Bei DOM stellen
sich mir immer die Nackenhaare auf; es ist für meinen Geschmack zu
javaesque. Wer Lisp kennt, weiß, wie man auf Bäume auch einacher
zugreifen kann.
Mein Lieblings-Rant dazu
http://harmful.cat-v.org/software/xml/s-exp_vs_XML (Erik Naggum schrieb
sehr pointiert, was nicht jedem gefällt)

KP
Stefan+ (Stefan Froehlich)
2022-06-10 10:15:06 UTC
Permalink
Post by Karl Pflästerer
Post by Stefan+ (Stefan Froehlich)
Post by Stefan+ (Stefan Froehlich)
Post by Karl Pflästerer
Mit https://www.php.net/manual/en/class.xmlreader.php bearbeiten
wir auch sehr große XML Dokumente; diese Klasse ist deutlich
speicherschonender. Der Ansatz ist (IMHO) schöner als SAX. das
https://www.php.net/manual/en/book.xml.php
Merci, da wird sich hoffentlich etwas machen lassen; ich brauche
es ja auch nur für die Formaterkennung, die Verarbeitung so
großer Files erfolgt dann eh durch eigene CLI-Programme, mit PHP
würde das ewig und ein Jahr dauern.
War dann gar nicht einmal so kompliziert, danke. Ein komplettes
Dokument möchte ich damit nicht parsen müssen, dafür ist es mir
zu rustikal; zur Formaterkennung reicht es aber ganz
ausgezeichnet.
Da sieht man, wie sich die Geschmäcker unterscheiden. Bei DOM
stellen sich mir immer die Nackenhaare auf; es ist für meinen
Geschmack zu javaesque.
Ich mag Java überhaupt nicht, aber DOM ist für den einen oder
anderen Standard sehr praktisch. Ich habe da z.B. einen, wo in einem
Element via XPath auf den eigentlichen Inhalt referenziert wird.
Dafür, dass das so ist, kann ich nichts, aber mit DOM ist das
(naheliegenderweise) sehr einfach gelöst. Zu Fuß? Ich weiss nicht.

Ich habe mit vielen, unterschiedlichen Formaten zu tun und mir im
Lauf der letzten zwei Jahre eine (noch längst nicht fertig
ausgerollte) Mapping-Engine geschrieben. Da kann ich dann (bei
kleineren Dateien, als die, um die es in diesem Thread ging) für ein
Format Dinge tun wie:

#v+
# basispfade
$responseInfo = '/opentrans:ORDERRESPONSE/opentrans:ORDERRESPONSE_HEADER/opentrans:ORDERRESPONSE_INFO/';

# mapping
$mapping = [
OrderResponse::FIELD_ORDER_NUMBER => $responseInfo . 'opentrans:ORDER_ID',
OrderResponse::FIELD_ALT_ORDER_NUMBER => $responseInfo . 'opentrans:ALT_CUSTOMER_ORDER_ID',
OrderResponse::FIELD_SUPPLIER_ORDER_NUMBER => $responseInfo . 'opentrans:SUPPLIER_ORDER_ID',
[...]
];
#v-

Dieses Mapping stecke ich dann gemeinsam mit der Definition der
zugehörigen Eingabefelder und dem (in diesem Fall XML-) Dokument in
eine verarbeitende Klasse und erhalte die fix-fertigen Datenwerte
als Ergebnis, inklusive Prüfung und ggf. Fehlermeldungen. Mit DOM
ist das dank XPath halbwegs einfach (wenn auch bei komplexeren
Strukturen natürlich nicht halb so übersichtlich, wie in den obigen
paar Zeilen), mit xmlreader sähe ich ad hoc keinen guten Zugang.
Post by Karl Pflästerer
Mein Lieblings-Rant dazu
http://harmful.cat-v.org/software/xml/s-exp_vs_XML (Erik Naggum
schrieb sehr pointiert, was nicht jedem gefällt)
Da kann ich auf zwei Arten darauf antworten:

a) ich habe die Standards nicht erfunden, sondern muss damit
arbeiten. Das ist zwar korrekt, allerdings ein bisschen feig, denn
ich mag XML ja. Daher

b) Overhead und Ressourcenverbrauch sind mir (leider mit Grenzen,
wie dieser Thread gezeigt hat) weitgehend egal, ich muss zum einen
sehr einfach korrekte Dokumente erzeugen können und, wichtiger noch,
sehr einfach fehlerhafte Dokumente korrigieren können, um sie
anschließend zu verarbeiten.

Ich bekomme andauernd XML-Dokumente, die Feher enthalten - weniger
im XML selber (auch das gibt's), sondern vor allem in den Nutzdaten.
Ungültige Codes, verletzte Längenbeschränkungen und Randbedingungen,
oder Fehler auf einer sehr hohen Ebene (Rechnungen, die auf falsche
Bestellungen Bezug nehmen etc). Mit XML kann ich die Datei in einem
Texteditor aufmachen, trivial korrigieren und danach verarbeiten; im
Anschluss gibt es einen Rüffel per Mail, der in der Regel wenig bis
gar nichts bewirkt. Mit anderen Datenformaten (die bekomme ich ja
auch) ist das ungleich komplizierter, sowohl was meine Analyse
betrifft, als auch schon überhaupt die Korrektur durch den
Ersteller. Da können all die Kritikpunkte noch so zutreffen; viele
davon sind (aus meiner Sicht) lediglich Feinheiten, während der
zentrale Vorteil von XML einfach unübertroffen ist.

Auch bei der oben genannten Mapping-Engine ist z.B. die abstrakte
Formulierung der Position eines Datums in EDIFACT ungleich
komplexer als in jedem mir bekannten XML-Standard mit Ausnahme von
IDOC, das aber eher als Persiflage von XML zu betrachten ist.

Servus,
Stefan
--
http://kontaktinser.at/ - die kostenlose Kontaktboerse fuer Oesterreich
Offizieller Erstbesucher(TM) von mmeike

Schlau? Schlauer als Stefan!? Glaube und Teste!
(Sloganizer)
Arno Welzel
2022-06-08 12:03:24 UTC
Permalink
Post by Stefan+ (Stefan Froehlich)
Ich habe ein paar Klassen, die unterschiedliche XML-Standards
erkennen (und in Abhängigkeit davon dann die passende
Weiterverarbeitung anstoßen, teilweise in PHP, teilweise extern).
Das läuft über DOMDocument und relativ simpel durch Abfrage der
obersten Elemente, Attribute u/o Namespaces.
| Allowed memory size of 12582912000 bytes exhausted (tried to allocate 13801920612 bytes)
Für den konkreten Fall habe ich das Speicherlimit halt von 12
auf 15GB erhöht - aber es ist abzusehen, dass auch das über kurz
oder lang gesprengt werden wird, und irgendwann kommen dann
physikalische Grenzen.
Was nicht überraschend ist, wenn das zugrundeliegende Dokument
entsprechend umfangreich ist.
Post by Stefan+ (Stefan Froehlich)
Und jetzt? Von DOMDocument auf Stringverarbeitung umstellen, die
ersten paar kB einlesen und mit regulären Ausdrücken darauf
herumhacken? So unelegant war die Software schon einmal, dorthin
möchte ich nur ungern zurück.
Gibt es Alternativen, die auf XML-Dokumenten arbeiten können, ohne
das Dokument vollständig im Speicher halten zu müssen?
Am ehesten das hier: <https://www.php.net/manual/en/book.xmlreader.php>

Siehe auch:
<https://stackoverflow.com/questions/911663/parsing-huge-xml-files-in-php>
--
Arno Welzel
https://arnowelzel.de
Loading...