W3docs

Java XML-Einführung

Überblick über XML-Verarbeitung in Java — DOM, SAX, StAX und JAXB im Vergleich.

XML (Extensible Markup Language) ist ein Textformat zur Darstellung strukturierter, hierarchischer Daten mithilfe verschachtelter Tags. Lange bevor JSON Web-APIs dominierte, war XML der Standard für Konfigurationsdateien, Dokumentformate und Nachrichtenaustausch — und es ist nach wie vor allgegenwärtig, von Maven-pom.xml-Dateien über SOAP-Services bis hin zu Office-Dokumenten.

Java bietet umfangreiche, integrierte XML-Unterstützung im JDK: Sie benötigen keine externe Bibliothek, um XML zu lesen oder zu schreiben. Die Pakete javax.xml.parsers und org.w3c.dom sowie org.xml.sax und javax.xml.stream stellen drei verschiedene Parser-Modelle bereit. Dieses Kapitel erklärt, was XML ist, welches Parser-Modell für welchen Anwendungsfall geeignet ist und wie sich XML von JSON unterscheidet — damit der Rest dieses Teils (DOM, SAX und JAXB) auf einem klaren Fundament aufbaut.

Diese Seite behandelt:

  • Wie ein XML-Dokument aufgebaut ist und die wichtigsten Begriffe (Element, Attribut, Root, wohlgeformt).
  • Die drei JDK-Parser-Modelle — DOM, SAX und StAX — und wann jedes passt.
  • Ein lauffähiges DOM-Beispiel mit ausschließlich JDK-Klassen.
  • Wie sich XML und JSON unterscheiden, damit Sie zwischen beiden wählen können.

Wie XML aussieht

Ein XML-Dokument ist ein Baum aus Elementen. Jedes Element hat einen Namen, optionale Attribute und entweder Textinhalt oder verschachtelte Kindelemente. Es gibt immer genau ein Root-Element, das alles umschließt.

<?xml version="1.0" encoding="UTF-8"?>
<catalog>
  <book id="1" lang="en">
    <title>Effective Java</title>
    <price>45.00</price>
  </book>
</catalog>

Hier ist <catalog> das Root-Element, <book> ist ein Kindelement mit zwei Attributen (id und lang), und <title> sowie <price> enthalten Text. Die XML-Deklaration in der ersten Zeile gibt Version und Zeichenkodierung an. Wohlgeformtes XML erfordert, dass jedes öffnende Tag geschlossen und korrekt verschachtelt ist.

Die drei Parser-Modelle

Das JDK bietet drei Möglichkeiten, XML zu lesen, jede mit einem anderen Kompromiss zwischen Komfort und Speicherbedarf. Die richtige Wahl ist die wichtigste XML-Entscheidung, die Sie treffen werden.

ModellStilSpeicherAm besten geeignet für
DOMLädt den gesamten Baum in den SpeicherHochWahlfreier Zugriff, Bearbeitung, kleine/mittlere Dokumente
SAXPush-Ereignisse beim Scannen (Callbacks)NiedrigGroße Dokumente, schreibgeschütztes Streaming
StAXPull-Ereignisse auf Anfrage (Cursor)NiedrigGroße Dokumente, mit einfacherem Kontrollfluss

DOM erstellt einen vollständigen In-Memory-Baum, den Sie frei navigieren und ändern können. SAX löst Callbacks aus (startElement, characters, endElement), während es liest, ohne das gesamte Dokument zu speichern. StAX ist ebenfalls stream-basiert, lässt aber Ihren Code das nächste Ereignis abrufen, wenn er bereit ist — was in der Regel leichter nachzuvollziehen ist als SAX-Callbacks.

DOM: der In-Memory-Baum

DOM ist das komfortabelste Modell, wenn Dokumente klein genug sind, um in den Speicher zu passen. Sie parsen einmal und durchlaufen oder befragen den Baum anschließend so oft Sie möchten.

import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.Document;
import org.w3c.dom.NodeList;

DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
Document doc = factory.newDocumentBuilder().parse("catalog.xml");

NodeList books = doc.getElementsByTagName("book");
System.out.println("Books: " + books.getLength());

getElementsByTagName gibt eine live NodeList zurück; Sie indizieren sie und casten Knoten auf Element, um Attribute und untergeordneten Text zu lesen. Das dedizierte Kapitel zum Java XML DOM-Parser führt ausführlich durch Navigation, Modifikation und Schreiben des Baums.

Warnung

By default the JDK parser resolves external entities, which exposes you to XXE (XML External Entity) attacks when parsing untrusted input. For production code that reads XML from outside your control, disable DTDs with factory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true); before creating the builder.

SAX und StAX: Streaming

Wenn ein Dokument zu groß ist, um es im Speicher zu halten, streamen Sie es. SAX schiebt Ereignisse an einen Handler, den Sie bereitstellen:

import javax.xml.parsers.SAXParserFactory;
import org.xml.sax.helpers.DefaultHandler;
import org.xml.sax.Attributes;

DefaultHandler handler = new DefaultHandler() {
    public void startElement(String uri, String local, String name, Attributes a) {
        System.out.println("Start: " + name);
    }
};
SAXParserFactory.newInstance().newSAXParser()
    .parse("catalog.xml", handler);

StAX gibt Ihnen einen Cursor, den Sie selbst weiterrücken — was viele klarer finden:

import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamReader;
import javax.xml.stream.XMLStreamConstants;
import java.io.FileReader;

XMLStreamReader r = XMLInputFactory.newInstance()
    .createXMLStreamReader(new FileReader("catalog.xml"));
while (r.hasNext()) {
    if (r.next() == XMLStreamConstants.START_ELEMENT) {
        System.out.println("Start: " + r.getLocalName());
    }
}

Im Kapitel zum Java XML SAX-Parser finden Sie eine vollständige Erläuterung der Ereignishandler. Wenn Sie das manuelle Parsen von Knoten überspringen und XML direkt auf Java-Objekte abbilden möchten, übernimmt JAXB die Bindung von Elementen an annotierte Klassen für Sie.

Ein eigenständiges Beispiel

Das folgende lauffähige Beispiel verwendet ausschließlich JDK-Klassen — kein Jackson oder JAXB erforderlich. Es parst einen XML-Katalog aus einem In-Memory-String mit DOM, durchläuft die <book>-Elemente, liest Attribute und untergeordneten Text und summiert die Preise.

java— editable, runs on the server

Was man aus der Ausführung mitnehmen kann:

  • DOM-Parsing benötigt keine externe Abhängigkeit — DocumentBuilderFactory und org.w3c.dom sind im JDK enthalten, weshalb das Programm Ergebnisse ausgibt, ohne dass sich etwas im Classpath befindet.
  • Der als catalog ausgegebene Name des Root-Elements bestätigt, dass es genau ein Root gibt, das das gesamte Dokument umschließt.
  • getElementsByTagName("book") gab eine NodeList der Länge 2 zurück, sodass Sie sie wie eine Liste indizieren und jedes Element auf Element casten können.
  • Attribute (id) werden mit getAttribute gelesen, während Textinhalt (title, price) mit getTextContent gelesen wird — beides sind verschiedene Arten von Daten am selben Element.
  • Da sich der gesamte Baum im Speicher befindet, ist die Summierung der Preise aller Bücher zu $83.50 einfach eine Schleife mit wahlfreiem Zugriff — der Komfort, der DOM seinen Speicheraufwand wert macht.

XML oder JSON?

XML und JSON lösen dasselbe Problem — strukturierte Daten austauschen — aber treffen unterschiedliche Kompromisse.

AspektXMLJSON
SyntaxAusführliche Tags, öffnend und schließendKompakte geschweifte und eckige Klammern
AttributeJa (id="1")Nein — alles ist ein Schlüssel/Wert-Paar
KommentareUnterstützt (<!-- ... -->)Nicht unterstützt
Schema/ValidierungAusgereift (XSD, DTD)JSON Schema, weniger verbreitet
JDK-UnterstützungIntegriert (javax.xml.*)Keine integriert — benötigt eine Bibliothek
Typischer Einsatz heuteConfig, Dokumente, SOAP, Legacy-SystemeWeb/REST APIs, moderne Services

Greifen Sie zu XML, wenn Sie ein vorhandenes XML-Format nutzen müssen (einen SOAP-Service, eine pom.xml, ein Office-Dokument) oder wenn Sie Attribute, Kommentare oder strenge Schema-Validierung benötigen. Greifen Sie zu JSON für neue Web-APIs, wo seine geringere Größe und native Browser-Unterstützung überzeugen.

Nächste Schritte

Übungen

Übung
Welches XML-Parser-Modell lädt das gesamte Dokument als navigierbaren Baum in den Speicher?
Welches XML-Parser-Modell lädt das gesamte Dokument als navigierbaren Baum in den Speicher?
Was this page helpful?