PHP SimpleXML
SimpleXML ist eine PHP-Erweiterung mit einer einfachen API zum Lesen und Bearbeiten von XML-Dokumenten mittels Eigenschaften und Array-Syntax.
Einführung
SimpleXML ist eine integrierte PHP-Erweiterung, die ein XML-Dokument in ein Objekt umwandelt, das mit normaler Eigenschaften- und Array-Syntax navigiert werden kann. Anstatt einen Knotenbaum manuell zu durchlaufen, schreibt man $xml->book->title — die Elementnamen werden zu Eigenschaften und sich wiederholende Elemente zu iterierbaren Listen.
Das macht SimpleXML zum schnellsten Weg, eine Konfigurationsdatei zu lesen, eine XML-API-Antwort zu verarbeiten oder ein kleines XML-Dokument zu erstellen. Diese Seite behandelt das Laden von XML, das Lesen von Elementen und Attributen, den Umgang mit Namespaces, Abfragen mit XPath, das Ändern von Dokumenten und den Umgang mit Parse-Fehlern.
SimpleXML eignet sich am besten für Dokumente, die bequem in den Speicher passen und eine bekannte, relativ flache Struktur haben. Für sehr große Dateien oder eine detaillierte, Low-Level-Kontrolle sind PHP XML DOM oder der Expat-basierte XML-Parser möglicherweise die bessere Wahl.
Ein XML-Dokument laden
Ein SimpleXMLElement wird aus einer von drei Quellen erstellt:
simplexml_load_string()— parst XML aus einem String (praktisch für API-Antworten).simplexml_load_file()— parst XML aus einer Datei oder URL.new SimpleXMLElement($xml)— der Konstruktor, der standardmäßig einen String akzeptiert.
Alle drei geben ein SimpleXMLElement zurück, das das Root-Element des Dokuments repräsentiert — keine Wrapper-Klasse um die gesamte Datei. Wenn das Root-Element <library> ist, ist das zurückgegebene Objekt <library>.
<?php
$data = <<<XML
<?xml version="1.0" encoding="UTF-8"?>
<library>
<book category="fiction">
<title>The Hobbit</title>
<author>J.R.R. Tolkien</author>
<price>14.99</price>
</book>
<book category="science">
<title>A Brief History of Time</title>
<author>Stephen Hawking</author>
<price>18.50</price>
</book>
</library>
XML;
$library = simplexml_load_string($data);
echo get_class($library); // SimpleXMLElementElemente und Attribute lesen
Untergeordnete Elemente werden als Eigenschaften abgerufen. Wenn ein Element sich wiederholt (wie <book>), verhält sich die Eigenschaft wie eine Liste, die mit [] indiziert oder mit foreach durchlaufen werden kann. Attribute werden mit Array-Syntax abgerufen ($element['attr']).
<?php
$library = simplexml_load_string($data); // the XML from above
echo $library->book[0]->title . "\n"; // The Hobbit
echo count($library->book) . "\n"; // 2
foreach ($library->book as $book) {
echo $book->title . " — " . $book['category'] . "\n";
}Ausgabe:
The Hobbit
2
The Hobbit — fiction
A Brief History of Time — scienceAchtung: Ein so abgerufenes Element ist ein
SimpleXMLElement, kein String.$book->pricewird dank der__toString()-Methode als Text ausgegeben, aber für Berechnungen oder strikte Vergleiche muss es zuerst gecastet werden:(float) $book->priceoder(string) $book['category']. Das Vergessen des Casts ist der häufigste SimpleXML-Fehler.
Abfragen mit XPath
Für alles, was über einfache Navigation hinausgeht — Filtern, Suchen tief im Baum, bedingte Auswahl — verwendet man xpath(). Es führt einen XPath-Ausdruck aus und gibt ein Array übereinstimmender Elemente zurück.
<?php
$library = simplexml_load_string($data);
// Titles of books priced over 10
foreach ($library->xpath('//book[price>10]/title') as $title) {
echo $title . "\n";
}
// The Hobbit
// A Brief History of TimeMit Namespaces arbeiten
Wenn ein Dokument XML-Namespaces verwendet, kann man auf Elemente mit Präfixen nicht über einfachen Eigenschaftszugriff zugreifen — man muss children() (für Elemente) oder attributes() (für Attribute) mit dem Namespace-URI aufrufen, oder das Präfix vor der XPath-Abfrage registrieren.
<?php
$rss = <<<XML
<rss xmlns:dc="http://purl.org/dc/elements/1.1/">
<channel>
<item>
<title>Hello</title>
<dc:creator>Jane Doe</dc:creator>
</item>
</channel>
</rss>
XML;
$xml = simplexml_load_string($rss);
$item = $xml->channel->item;
// Access the dc: namespace by URI
$dc = $item->children('http://purl.org/dc/elements/1.1/');
echo $dc->creator . "\n"; // Jane DoeXML ändern und erstellen
SimpleXML kann bestehende Knoten ändern, neue hinzufügen und das Ergebnis serialisieren. Einer Eigenschaft einen Wert zuweisen ändert diesen, addChild() hängt ein Element an und addAttribute() fügt ein Attribut hinzu. asXML() gibt das Dokument als String zurück oder schreibt es in eine Datei, wenn ein Pfad übergeben wird.
<?php
$book = simplexml_load_string('<book><title>Old Title</title><price>10.00</price></book>');
$book->title = 'New Title'; // change an existing value
$book->price = '12.50';
$book->addChild('author', 'Jane Doe'); // add a new element
$book->addAttribute('id', '42'); // add an attribute
echo $book->asXML();Ausgabe:
<?xml version="1.0"?>
<book id="42"><title>New Title</title><price>12.50</price><author>Jane Doe</author></book>Die Übergabe eines Dateinamens — $book->asXML('book.xml') — schreibt das Dokument stattdessen auf die Festplatte und gibt bei Erfolg true zurück. Weitere Details unter asXML().
Parse-Fehler behandeln
Wenn das XML fehlerhaft ist, geben die Ladefunktionen false zurück und erzeugen PHP-Warnungen. Um Fehler still zu erfassen und selbst zu prüfen, aktiviert man die interne Fehlerbehandlung mit libxml_use_internal_errors() und liest sie mit libxml_get_errors() aus.
<?php
libxml_use_internal_errors(true);
$broken = "<library><book><title>Unclosed</book></library>";
$xml = simplexml_load_string($broken);
if ($xml === false) {
echo "Failed to parse XML:\n";
foreach (libxml_get_errors() as $error) {
echo trim($error->message) . "\n";
}
libxml_clear_errors();
}Ausgabe:
Failed to parse XML:
Opening and ending tag mismatch: title line 1 and book
Opening and ending tag mismatch: book line 1 and library
Premature end of data in tag library line 1Den Rückgabewert sollte man immer prüfen, bevor das Ergebnis verwendet wird — ein false als Objekt zu behandeln führt zu "attempt to read property on bool"-Fehlern im weiteren Code.
Zusammenfassung
- XML laden mit
simplexml_load_string(),simplexml_load_file()odernew SimpleXMLElement(); das zurückgegebene Objekt ist das Root-Element. - Untergeordnete Elemente als Eigenschaften und Attribute als Array-Schlüssel lesen; vor Vergleichen oder Berechnungen zu
(string),(int)oder(float)casten. xpath()für Filterung und tiefe Abfragen verwenden, undchildren()/attributes()mit einer URI für Dokumente mit Namespaces.- Mit Eigenschaftszuweisung,
addChild()undaddAttribute()ändern, dann mitasXML()serialisieren. - Gegen fehlerhafte Eingaben mit
libxml_use_internal_errors()undlibxml_get_errors()absichern.
Für weiterführende Informationen siehe Knotenwerte mit SimpleXML lesen, die SimpleXML-Parser-Übersicht und die Low-Level-libxml-Funktionen.