SimpleXML in PHP: Ein umfassender Leitfaden
SimpleXML ist ein leistungsstarkes PHP-Werkzeug zum Parsen und Bearbeiten von XML-Daten. Dieses Tutorial zeigt die Verwendung von SimpleXML in PHP.
SimpleXML ist eine eingebaute PHP-Erweiterung, die ein XML-Dokument in einen Baum von Objekten umwandelt, den Sie mit gewöhnlicher PHP-Syntax lesen, durchlaufen und ändern können. Dieses Tutorial behandelt das Laden von XML, das Lesen von Elementen und Attributen, den Umgang mit Namespaces, das Ändern von Knoten und das Zurückschreiben des Ergebnisses — mit ausführbaren Beispielen und den Fallstricken, über die man stolpert.
Einführung in SimpleXML
SimpleXML ist eine PHP-Erweiterung, mit der Sie XML-Daten mit sehr wenig Code parsen und bearbeiten können. Sie unterscheidet sich von der DOM-Erweiterung, beide basieren jedoch auf derselben libxml2-Bibliothek und teilen daher deren Fehlerbehandlung. Der Kompromiss ist einfach:
- SimpleXML — am besten zum Lesen von wohlgeformtem XML, bei dem Sie größtenteils eine bekannte Struktur durchlaufen. Prägnanter, objektähnlicher Zugriff.
- DOM — besser für umfangreiches Bearbeiten, das Verschieben von Knoten oder wenn Sie die volle Kontrolle über den Dokumentbaum benötigen.
SimpleXML ist in Standard-PHP-Builds standardmäßig aktiviert, sodass in der Regel nichts installiert werden muss.
XML laden
Es gibt zwei Einstiegspunkte. Verwenden Sie simplexml_load_file() für eine Datei oder URL und simplexml_load_string() für XML, das Sie bereits als String vorliegen haben (zum Beispiel eine API-Antwort).
Da beide Funktionen auf libxml2 basieren, löst ein fehlerhaftes Dokument PHP-Warnungen aus und gibt false zurück. Wechseln Sie immer zuerst zur internen Fehlerbehandlung mit libxml_use_internal_errors(), damit Sie die Fehler selbst prüfen können, anstatt Warnungen in der Ausgabe zu erzeugen:
Eine XML-Datei laden
libxml_use_internal_errors(true);
$xml = simplexml_load_file('data.xml');
if ($xml === false) {
foreach (libxml_get_errors() as $error) {
echo trim($error->message), PHP_EOL;
}
die('Failed to load XML.');
}simplexml_load_string() funktioniert identisch, nimmt aber den XML-Text direkt entgegen:
XML aus einem String laden
$source = '<data><item><name>John Doe</name></item></data>';
$xml = simplexml_load_string($source);In beiden Fällen ist der Rückgabewert ein SimpleXMLElement, das das Wurzelelement des Dokuments repräsentiert.
Auf Elemente zugreifen
SimpleXML ordnet jedes Kind-Element einer Eigenschaft des übergeordneten Objekts zu, auf die mit dem PHP-Objektoperator -> zugegriffen wird (nicht mit Punktnotation — PHP hat keinen .-Memberzugriff). Wiederholte Kind-Elemente werden per Index angesprochen. Betrachten Sie dieses XML:
XML-Beispiel
<data>
<item>
<name>John Doe</name>
<age>30</age>
</item>
<item>
<name>Jane Doe</name>
<age>28</age>
</item>
</data>Lesen Sie das erste Element und durchlaufen Sie dann alle item-Elemente mit foreach:
Auf Elementwerte zugreifen
// The first <item> (index 0)
$name = $xml->item[0]->name;
$age = $xml->item[0]->age;
// Iterate through all <item> elements
foreach ($xml->item as $item) {
echo $item->name . ' is ' . $item->age . ' years old.' . PHP_EOL;
}Der String-Cast-Fallstrick
$item->name ist kein String — es ist ein SimpleXMLElement. Es sieht nur wie ein String aus, wenn es ausgegeben wird, weil das Element in String-Kontexten automatisch umgewandelt wird. Wenn Sie es in einem Array speichern, an json_encode() übergeben oder streng vergleichen, casten Sie es vorher explizit:
$name = (string) $xml->item[0]->name; // plain string
$age = (int) $xml->item[0]->age; // plain intAttribute lesen
Element-Attribute werden mit Array-Syntax abgerufen, nicht mit dem -> Operator. Für <item id="1" status="active"> liest man sie so:
Auf Attribute zugreifen
$id = (string) $xml->item[0]['id']; // "1"
$status = (string) $xml->item[0]['status']; // "active"
// Loop over every attribute on an element
foreach ($xml->item[0]->attributes() as $key => $value) {
echo "$key = $value" . PHP_EOL;
}Mit Namespaces arbeiten
XML, das Namespaces verwendet (Präfixe wie <atom:link>), lässt sich nicht über einfachen Property-Zugriff auflösen — Sie müssen den Namespace mit children() registrieren oder eine XPath-Abfrage verwenden. Das ist der häufigste Grund, warum „das Element leer ist", obwohl es eindeutig in der Datei vorhanden ist:
Namespace-Elemente
$source = '<feed xmlns:atom="http://www.w3.org/2005/Atom">'
. '<atom:title>Hello</atom:title></feed>';
$xml = simplexml_load_string($source);
$atom = $xml->children('http://www.w3.org/2005/Atom');
echo (string) $atom->title; // "Hello"Mit XPath abfragen
Für alles, was tiefer als ein direktes Kind-Element liegt, gibt xpath() ein Array passender Elemente zurück — viel übersichtlicher als verschachtelte Schleifen:
// Every <name> anywhere under the root
foreach ($xml->xpath('//name') as $name) {
echo (string) $name . PHP_EOL;
}Elemente ändern und hinzufügen
Sie können einen Wert durch Zuweisung an die Eigenschaft ändern und den Baum mit addChild() / addAttribute() erweitern:
Knoten ändern und erstellen
// Change existing values
$xml->item[0]->name = 'John Smith';
$xml->item[0]->age = 32;
// Add a brand-new child element and an attribute
$new = $xml->addChild('item');
$new->addChild('name', 'New Person');
$new->addAttribute('id', '99');Eine Wertzuweisung ersetzt den Textinhalt des Elements; addChild() hängt ein neues Element an, anstatt ein vorhandenes zu überschreiben.
Zurück in XML konvertieren
Verwenden Sie die Methode asXML(), um den (möglicherweise geänderten) Baum wieder in einen String zu serialisieren, und schreiben Sie ihn dann mit file_put_contents():
Änderungen als XML speichern
file_put_contents('data.xml', $xml->asXML());Ohne Argument aufgerufen gibt asXML() das vollständige Dokument als String zurück einschließlich der <?xml version="1.0"?>-Deklaration — genau das, was Sie zum Speichern benötigen. Rufen Sie es auf einem Kind-Element auf ($xml->item[0]->asXML()), um nur dieses Fragment ohne Deklaration zu erhalten.
Fazit
SimpleXML ist der schnellste Weg, um wohlgeformtes XML in PHP zu lesen und leicht zu bearbeiten: Laden mit simplexml_load_file() oder simplexml_load_string(), den Baum mit -> und Array-Indizierung durchlaufen, Attribute mit [] lesen und mit asXML() zurückschreiben. Denken Sie an die beiden wiederkehrenden Fallstricke — Elemente vor der Wiederverwendung in Strings casten und Namespaces vor dem Zugriff auf Präfix-Knoten registrieren. Für umfangreiches, programmgesteuertes Bearbeiten von Dokumenten greifen Sie stattdessen auf die DOM-Erweiterung zurück. Um tiefer einzusteigen, fahren Sie mit PHP SimpleXML und Daten lesen mit SimpleXML get fort.