XML bleibt trotz der zunehmenden Verbreitung von JSON ein fester Bestandteil vieler PHP-Projekte. Konfigurationsdateien, SOAP-Schnittstellen, RSS-Feeds und Datenexporte setzen nach wie vor auf die Extensible Markup Language. PHP bietet mit SimpleXML, DOMDocument und XMLReader drei leistungsfähige Parser, die jeweils für unterschiedliche Anwendungsfälle optimiert sind. Dieses Tutorial zeigt Schritt für Schritt, wie XML-Dateien eingelesen, durchsucht und programmatisch erstellt werden.
Was ist XML?
XML (Extensible Markup Language) ist ein textbasiertes Format zur Strukturierung von Daten. Im Gegensatz zu HTML dient XML nicht der Darstellung, sondern ausschließlich dem Transport und der Speicherung von Informationen. Jedes XML-Dokument besteht aus Elementen, die durch öffnende und schließende Tags begrenzt werden. Elemente können Attribute enthalten und beliebig tief verschachtelt sein. Ein gültiges XML-Dokument beginnt mit einer optionalen XML-Deklaration und besitzt genau ein Wurzelelement, das alle weiteren Elemente umschließt. Obwohl JSON in vielen modernen APIs als bevorzugtes Austauschformat gilt, bleibt XML für SOAP-Webservices, RSS-Feeds, SVG-Grafiken und zahlreiche Konfigurationsdateien unverzichtbar.
<?php
$xmlString = '<?xml version="1.0" encoding="UTF-8"?>
<buecher>
<buch kategorie="Programmierung">
<titel>PHP Grundlagen</titel>
<autor>Max Mustermann</autor>
<preis>29.99</preis>
</buch>
<buch kategorie="Datenbanken">
<titel>MySQL kompakt</titel>
<autor>Erika Musterfrau</autor>
<preis>34.95</preis>
</buch>
</buecher>';
echo $xmlString;
Dieses Beispiel zeigt ein typisches XML-Dokument mit einem Wurzelelement <buecher>, das zwei <buch>-Elemente enthält. Jedes Buch besitzt ein Attribut kategorie sowie die Kindelemente <titel>, <autor> und <preis>. Genau solche Strukturen lassen sich in PHP mit verschiedenen Parsern einlesen und verarbeiten.
Die PHP XML Parser im Überblick
Bevor ein Parser ausgewählt wird, lohnt sich ein Vergleich der verfügbaren Optionen. PHP stellt mehrere XML-Parser bereit, die sich in Funktionsumfang und Speicherverbrauch deutlich unterscheiden.
flowchart TD
A["XML-Daten in PHP"] --> B{"Anwendungsfall?"}
B -->|"Einfach lesen"| C["SimpleXML"]
B -->|"Lesen und Schreiben"| D["DOMDocument"]
B -->|"Grosse Dateien"| E["XMLReader"]
B -->|"Gezielt suchen"| F["XPath"]
C --> G["Kleine bis mittlere Dateien"]
D --> H["Volle DOM-Kontrolle"]
E --> I["Speicherschonend streamen"]
F --> J["Kombinierbar mit DOM und SimpleXML"]
SimpleXML wandelt ein XML-Dokument in ein PHP-Objekt um und ermöglicht den Zugriff auf Elemente über Objekteigenschaften. Dieser Parser eignet sich hervorragend für kleine bis mittelgroße Dateien, bietet aber keine Möglichkeit, XML-Dokumente zu verändern oder neu zu erstellen. DOMDocument implementiert die vollständige DOM-Spezifikation und erlaubt sowohl das Lesen als auch das Erstellen und Ändern von XML. Der XMLReader arbeitet als Pull-Parser und liest das Dokument Element für Element, ohne es vollständig in den Speicher zu laden. Damit ist er die erste Wahl für große XML-Dateien mit mehreren Megabyte oder Gigabyte.
XML lesen mit SimpleXML
SimpleXML ist der einfachste Weg, um XML-Daten in PHP zu verarbeiten. Die Funktionen simplexml_load_string() und simplexml_load_file() wandeln einen XML-String beziehungsweise eine XML-Datei in ein SimpleXMLElement-Objekt um.
<?php
$xml = simplexml_load_string('<?xml version="1.0"?>
<buecher>
<buch>
<titel>PHP Grundlagen</titel>
<autor>Max Mustermann</autor>
<preis>29.99</preis>
</buch>
<buch>
<titel>PHP Fortgeschritten</titel>
<autor>Erika Musterfrau</autor>
<preis>39.99</preis>
</buch>
</buecher>');
foreach ($xml->buch as $buch) {
echo $buch->titel . ' von ' . $buch->autor . PHP_EOL;
}
/*
PHP Grundlagen von Max Mustermann
PHP Fortgeschritten von Erika Musterfrau
*/
Der Zugriff auf Kindelemente erfolgt über die Pfeilnotation $xml->buch. PHP durchläuft dabei alle gleichnamigen Elemente automatisch in einer foreach-Schleife. Attribute lassen sich über die Array-Syntax auslesen: $buch['kategorie'] liefert den Wert des Attributs kategorie. Um eine XML-Datei statt eines Strings zu laden, wird simplexml_load_file('pfad/zur/datei.xml') verwendet. Bei CDATA-Sektionen muss der Wert mit (string) gecastet werden, damit PHP den Inhalt korrekt als Text zurückgibt. SimpleXML gibt bei fehlenden Elementen kein null zurück, sondern ein leeres SimpleXMLElement-Objekt. Eine Prüfung mit isset() vor dem Zugriff auf optionale Elemente vermeidet daher unerwartete Ergebnisse.
XML lesen mit DOMDocument
Während SimpleXML für schnelles Einlesen optimiert ist, bietet DOMDocument die volle Kontrolle über die Baumstruktur eines XML-Dokuments. Elemente werden über Methoden wie getElementsByTagName() navigiert, und jeder Knoten stellt Eigenschaften wie textContent und nodeValue bereit.
<?php
$doc = new DOMDocument();
$doc->loadXML('<?xml version="1.0"?>
<buecher>
<buch kategorie="Programmierung">
<titel>PHP Grundlagen</titel>
<autor>Max Mustermann</autor>
<preis>29.99</preis>
</buch>
<buch kategorie="Datenbanken">
<titel>MySQL kompakt</titel>
<autor>Erika Musterfrau</autor>
<preis>34.95</preis>
</buch>
</buecher>');
$buecher = $doc->getElementsByTagName('buch');
foreach ($buecher as $buch) {
$titel = $buch->getElementsByTagName('titel')
->item(0)->textContent;
$kategorie = $buch->getAttribute('kategorie');
echo $titel . ' (' . $kategorie . ')' . PHP_EOL;
}
/*
PHP Grundlagen (Programmierung)
MySQL kompakt (Datenbanken)
*/
Die Methode loadXML() lädt einen XML-String, während load() eine Datei von der Festplatte einliest. Mit getElementsByTagName() wird eine DOMNodeList aller Elemente mit dem angegebenen Tagnamen zurückgegeben. Attribute werden über getAttribute() am jeweiligen Knoten abgefragt. Der entscheidende Vorteil gegenüber SimpleXML liegt darin, dass DOMDocument die Struktur eines Dokuments auch verändern und neue Elemente hinzufügen kann.
XML durchsuchen mit XPath
XPath ist eine Abfragesprache, die gezielte Suchen innerhalb eines XML-Dokuments ermöglicht. In PHP steht XPath sowohl über DOMXPath als auch über die Methode xpath() von SimpleXML zur Verfügung.
<?php
$doc = new DOMDocument();
$doc->loadXML('<?xml version="1.0"?>
<buecher>
<buch kategorie="Programmierung">
<titel>PHP Grundlagen</titel>
<autor>Max Mustermann</autor>
<preis>29.99</preis>
</buch>
<buch kategorie="Datenbanken">
<titel>MySQL kompakt</titel>
<autor>Erika Musterfrau</autor>
<preis>34.95</preis>
</buch>
<buch kategorie="Programmierung">
<titel>PHP Fortgeschritten</titel>
<autor>Erika Musterfrau</autor>
<preis>44.50</preis>
</buch>
</buecher>');
$xpath = new DOMXPath($doc);
/* Alle Buecher mit Preis groesser als 30 */
$teureBuecher = $xpath->query('//buch[preis > 30]/titel');
foreach ($teureBuecher as $titel) {
echo $titel->textContent . PHP_EOL;
}
/*
MySQL kompakt
PHP Fortgeschritten
*/
/* Alle Buecher der Kategorie Programmierung */
$progBuecher = $xpath->query('//buch[@kategorie="Programmierung"]/titel');
foreach ($progBuecher as $titel) {
echo $titel->textContent . PHP_EOL;
}
/*
PHP Grundlagen
PHP Fortgeschritten
*/
Der XPath-Ausdruck //buch[preis > 30]/titel findet alle <titel>-Elemente, deren Geschwisterelement <preis> einen Wert größer als 30 hat. Mit @kategorie wird auf Attribute zugegriffen. XPath Ausdrücke lassen sich beliebig kombinieren und verschachteln, was sie zu einem mächtigen Werkzeug für komplexe Abfragen macht. Bei SimpleXML funktioniert die Suche ähnlich: $xml->xpath('//buch[preis > 30]') gibt ein Array von SimpleXMLElement-Objekten zurück. XPath unterstützt außerdem Funktionen wie contains(), starts-with() und count(), mit denen sich noch präzisere Abfragen formulieren lassen. Gerade bei tief verschachtelten XML-Strukturen spart XPath gegenüber manueller Navigation mit verschachtelten Schleifen erheblich an Code.
Große XML-Dateien mit XMLReader verarbeiten
Sowohl SimpleXML als auch DOMDocument laden das gesamte XML-Dokument in den Arbeitsspeicher. Bei Dateien mit mehreren hundert Megabyte führt das schnell zu Speicherproblemen. Der XMLReader arbeitet stattdessen als sogenannter Pull-Parser und liest das Dokument Knoten für Knoten, ohne es vollständig im Speicher vorzuhalten.
<?php
$reader = new XMLReader();
$reader->open('grosse-datei.xml');
while ($reader->read()) {
if ($reader->nodeType === XMLReader::ELEMENT
&& $reader->localName === 'buch'
) {
$node = new SimpleXMLElement(
$reader->readOuterXml()
);
echo $node->titel . ': ' . $node->preis . PHP_EOL;
}
}
$reader->close();
Die Methode read() bewegt den Cursor zum nächsten Knoten im Dokument. Mit nodeType und localName wird geprüft, ob der aktuelle Knoten ein <buch>-Element ist. Trifft das zu, wird das einzelne Element mit readOuterXml() extrahiert und an SimpleXML übergeben. Auf diese Weise verbindet sich die Speichereffizienz des XMLReaders mit der komfortablen Objektsyntax von SimpleXML. Nach Abschluss der Verarbeitung sollte close() aufgerufen werden, um die Ressource freizugeben. Der XMLReader eignet sich besonders für Szenarien wie den Import großer Produktkataloge, das Einlesen umfangreicher Logdateien oder die Verarbeitung von Datenexporten, bei denen der Speicherverbrauch eine entscheidende Rolle spielt.
XML-Dokumente erstellen
Neben dem Einlesen bestehender XML-Daten kann PHP auch neue XML-Dokumente programmatisch erzeugen. Dafür eignet sich DOMDocument, da es die vollständige Kontrolle über Elemente, Attribute und Textinhalte bietet.
<?php
$doc = new DOMDocument('1.0', 'UTF-8');
$doc->formatOutput = true;
/* Wurzelelement erstellen */
$root = $doc->createElement('buecher');
$doc->appendChild($root);
/* Erstes Buch hinzufuegen */
$buch = $doc->createElement('buch');
$buch->setAttribute('kategorie', 'Programmierung');
$root->appendChild($buch);
$titel = $doc->createElement('titel', 'Neues PHP Buch');
$buch->appendChild($titel);
$autor = $doc->createElement('autor', 'Anna Beispiel');
$buch->appendChild($autor);
$preis = $doc->createElement('preis', '24.99');
$buch->appendChild($preis);
/* Zweites Buch hinzufuegen */
$buch2 = $doc->createElement('buch');
$buch2->setAttribute('kategorie', 'Webentwicklung');
$root->appendChild($buch2);
$titel2 = $doc->createElement('titel', 'HTML und CSS');
$buch2->appendChild($titel2);
$autor2 = $doc->createElement('autor', 'Tom Weber');
$buch2->appendChild($autor2);
$preis2 = $doc->createElement('preis', '19.95');
$buch2->appendChild($preis2);
echo $doc->saveXML();
/*
<?xml version="1.0" encoding="UTF-8"?>
<buecher>
<buch kategorie="Programmierung">
<titel>Neues PHP Buch</titel>
<autor>Anna Beispiel</autor>
<preis>24.99</preis>
</buch>
<buch kategorie="Webentwicklung">
<titel>HTML und CSS</titel>
<autor>Tom Weber</autor>
<preis>19.95</preis>
</buch>
</buecher>
*/
Die Eigenschaft formatOutput = true sorgt für eine saubere Einrückung der Ausgabe. Mit createElement() werden neue Knoten erzeugt und mit appendChild() in die Baumstruktur eingefügt. Attribute werden über setAttribute() am jeweiligen Element gesetzt. Die Methode saveXML() gibt das fertige Dokument als String zurück, während save('datei.xml') es direkt in eine Datei schreibt. Auf diese Weise lassen sich XML-Exporte, Sitemaps oder Konfigurationsdateien dynamisch generieren.
Namespaces in XML
Viele professionelle XML-Formate verwenden Namespaces, um Namenskonflikte zwischen Elementen aus unterschiedlichen Quellen zu vermeiden. In PHP müssen Namespaces bei der Abfrage explizit berücksichtigt werden, da Elemente mit Namespace sonst nicht gefunden werden.
<?php
$xmlString = '<?xml version="1.0"?>
<katalog xmlns:inv="http://example.com/inventar">
<inv:produkt>
<inv:name>Laptop</inv:name>
<inv:bestand>42</inv:bestand>
</inv:produkt>
<inv:produkt>
<inv:name>Monitor</inv:name>
<inv:bestand>15</inv:bestand>
</inv:produkt>
</katalog>';
$xml = simplexml_load_string($xmlString);
$namespaces = $xml->getNamespaces(true);
foreach ($xml->children($namespaces['inv']) as $produkt) {
$name = $produkt->children($namespaces['inv'])->name;
$bestand = $produkt->children($namespaces['inv'])->bestand;
echo $name . ': ' . $bestand . ' Stueck' . PHP_EOL;
}
/*
Laptop: 42 Stueck
Monitor: 15 Stueck
*/
Die Methode getNamespaces(true) liefert alle im Dokument verwendeten Namespaces als assoziatives Array. Mit children($namespace) wird auf die Kindelemente innerhalb eines bestimmten Namespace zugegriffen. Bei DOMXPath müssen Namespaces vor der Abfrage mit registerNamespace() registriert werden. Ohne diese Registrierung liefern XPath Ausdrücke auf Elemente mit Namespace ein leeres Ergebnis. Namespaces begegnen PHP-Entwicklern häufig bei der Arbeit mit SOAP-Antworten, Atom-Feeds und branchenspezifischen XML-Standards. Es empfiehlt sich, die Namespace-URIs nicht fest im Code zu hinterlegen, sondern sie dynamisch aus dem Dokument auszulesen, um flexibel auf Änderungen reagieren zu können.
Fazit
PHP bietet mit SimpleXML, DOMDocument und XMLReader drei leistungsfähige Werkzeuge für die Arbeit mit XML. SimpleXML eignet sich ideal zum schnellen Einlesen kleiner bis mittelgroßer Dateien und besticht durch seine intuitive Objektsyntax. DOMDocument bietet die volle Kontrolle über die Baumstruktur und ist der richtige Parser, wenn XML-Dokumente nicht nur gelesen, sondern auch verändert oder neu erstellt werden sollen. Für große Dateien mit mehreren hundert Megabyte ist der XMLReader die speicherschonende Wahl, da er das Dokument nicht vollständig in den Arbeitsspeicher lädt. XPath ergänzt alle drei Parser als Abfragesprache für gezielte Suchen innerhalb der XML-Struktur. Wer Namespaces berücksichtigen muss, sollte die Methoden getNamespaces() und registerNamespace() kennen. JSON hat XML in vielen Bereichen abgelöst, doch für SOAP-Schnittstellen, RSS-Feeds und Konfigurationsdateien bleibt XML ein unverzichtbares Format in der PHP-Entwicklung.