Ich habe es in den letzten fünfzehn Jahren immer wieder erlebt: Ein Entwickler bekommt die Aufgabe, Daten aus einer XML-Datei zu extrahieren, googelt kurz nach Java How To Parse XML und landet bei einem veralteten Tutorial, das DOM empfiehlt. Drei Wochen später bricht das System am Black Friday zusammen, weil die 500 MB große Lieferanten-Datei den Heap-Speicher des Servers innerhalb von Sekunden gefressen hat. Der Schaden? Zehntausende Euro an entgangenen Umsätzen und ein Team, das das gesamte Wochenende mit der Fehlersuche verbringt, nur um festzustellen, dass die Architektur von Grund auf falsch war. Wer denkt, XML sei ein gelöstes Problem der frühen 2000er, irrt sich gewaltig. Es ist eine Mine, die darauf wartet, hochzugehen, wenn man sie mit dem falschen Werkzeug berührt.
Die Speicherfalle von DocumentBuilderFactory und DOM
Der häufigste Fehler, den ich bei Junior-Entwicklern sehe, ist der Griff zu DOM (Document Object Model). Es sieht auf dem Papier toll aus. Man lädt die Datei, bekommt einen schönen Baum und kann darin herumspringen. Aber hier ist die harte Realität: DOM benötigt etwa das Fünf- bis Zehnfache der eigentlichen Dateigröße an Arbeitsspeicher. Wenn du eine 100 MB Datei parst, sind plötzlich 1 GB RAM weg. In einer Cloud-Umgebung, in der du für RAM bezahlst, ist das pures Geldverbrennen.
In meiner Zeit bei einem großen Logistikdienstleister hatten wir ein System, das XML-Manifeste verarbeitete. Die Entwickler dachten, DOM sei der Standardweg für Java How To Parse XML. Bei kleinen Testdateien lief alles super. Als dann die echten Daten von den Frachtschiffen kamen, warf die JVM nur noch OutOfMemoryError am Fließband. Wir mussten den gesamten Parser in einer Nachtschicht auf SAX (Simple API for XML) umstellen. Das Problem bei SAX ist allerdings, dass der Code aussieht wie ein Unfall in einer Spaghettifabrik, weil man den Zustand manuell verwalten muss.
Die Lösung liegt bei StAX
Wer heute noch SAX oder DOM für große Datenmengen nutzt, hat die letzten 15 Jahre Java-Entwicklung verschlafen. StAX (Streaming API for XML) ist der Weg. Es ist ein Pull-Parser. Das bedeutet, dein Code fragt aktiv nach dem nächsten Element, anstatt von einem Event-Handler (SAX) bombardiert zu werden oder das ganze Ding in den Speicher zu laden (DOM). Du behältst die Kontrolle über den Cursor. Das spart nicht nur Speicher, sondern macht den Code auch lesbar. Wer effizient arbeiten will, nutzt den XMLStreamReader. Er ist schnell, speicherschonend und stabil.
Warum JAXB dich in falscher Sicherheit wiegt
Ein weiterer teurer Irrtum ist die blinde Nutzung von JAXB (Java Architecture for XML Binding). Versteh mich nicht falsch, JAXB ist großartig für Webservices mit festen Schemas. Aber sobald du XML-Dateien von Drittanbietern bekommst, die es mit der Struktur nicht so genau nehmen oder riesige Listen enthalten, wird JAXB zum Albtraum. JAXB versucht, die gesamte Struktur in Java-Objekte zu mappen. Das ist im Grunde DOM mit einem schicken Anzug. Es frisst Speicher.
Ich erinnere mich an ein Projekt im Bankensektor, bei dem Transaktionsdaten im XML-Format verarbeitet wurden. Das Team nutzte JAXB, weil es „modern“ wirkte. Das Problem war, dass die XML-Struktur so tief verschachtelt war, dass die generierten Java-Klassen unbedienbar wurden. Jede kleine Änderung am Schema des Partners führte dazu, dass der gesamte Code neu generiert werden musste. Wir haben Wochen mit Debugging verbracht, weil ein optionales Feld plötzlich fehlte und JAXB mit einer kryptischen Fehlermeldung ausstieg.
Hybrid-Parsing ist der Profi-Weg
Wenn du JAXB liebst, aber große Dateien hast, dann kombiniere es mit StAX. Du nutzt StAX, um durch die Datei zu iterieren, bis du zu einem Element kommst, das dich interessiert (zum Beispiel eine einzelne `