Beim Verarbeiten von XML Daten in PHP stellt sich oft die Frage, wie einzelne Elemente, Attribute oder Knoten gezielt aus einem Dokument extrahiert werden können. XPath ist eine Abfragesprache, die genau dieses Problem löst. Sie ermöglicht es, mit kompakten Ausdrücken durch die Baumstruktur eines XML Dokuments zu navigieren und bestimmte Nodes präzise anzusprechen. PHP bietet dafür zwei Ansätze: die Klasse DOMXPath in Kombination mit DOMDocument sowie die Methode SimpleXMLElement::xpath(). Dieses Tutorial erklärt beide Varianten, zeigt die wichtigsten XPath Ausdrücke und behandelt Sonderfälle wie Namespaces und HTML Dokumente.

Bevor die PHP-Funktionen zum Einsatz kommen, lohnt sich ein kurzer Überblick über die XPath-Syntax und ihre wichtigsten Ausdrücke.
XPath Grundlagen
Bevor XPath in PHP eingesetzt wird, lohnt sich ein kurzer Blick auf die grundlegende Syntax. XPath Ausdrücke beschreiben Pfade innerhalb der Baumstruktur eines XML Dokuments. Ein einzelner Schrägstrich / steht für den Wurzelknoten, ein doppelter Schrägstrich // sucht auf allen Ebenen. Eckige Klammern [] dienen als Prädikate, um die Ergebnismenge weiter einzuschränken. Das @ Zeichen spricht Attribute an.
Die folgende Tabelle fasst die wichtigsten Ausdrücke zusammen:
| Ausdruck | Bedeutung |
//buch | Alle buch Elemente im gesamten Dokument |
/bibliothek/buch | Alle buch Elemente direkt unter bibliothek |
//buch[@isbn] | Alle buch Elemente mit dem Attribut isbn |
//buch[1] | Das erste buch Element |
//buch/titel/text() | Der Textinhalt aller titel Elemente in buch |
Das folgende Diagramm veranschaulicht den Ablauf einer XPath Abfrage in PHP und die beiden verfügbaren APIs.
flowchart TD
A["XML-Dokument laden"] --> B{"Welche API?"}
B --> C["DOMDocument + DOMXPath"]
B --> D["SimpleXML + xpath()"]
C --> E["query('//element')"]
D --> F["xpath('//element')"]
E --> G["DOMNodeList"]
F --> H["Array von SimpleXMLElement"]
XPath mit DOMXPath verwenden
Die Klasse DOMXPath arbeitet auf einem DOMDocument Objekt und gibt bei einer Abfrage eine DOMNodeList zurück. Dieser Ansatz bietet volle Kontrolle über das Dokument und eignet sich besonders für komplexe Abfragen.
<?php
$xml = '<?xml version="1.0" encoding="UTF-8"?>
<bibliothek>
<buch isbn="978-3-123">
<titel>PHP Grundlagen</titel>
<autor>Max Mustermann</autor>
<preis>29.90</preis>
</buch>
<buch isbn="978-3-456">
<titel>PHP Fortgeschritten</titel>
<autor>Erika Musterfrau</autor>
<preis>39.90</preis>
</buch>
<buch isbn="978-3-789">
<titel>XML und XPath</titel>
<autor>Hans Beispiel</autor>
<preis>24.50</preis>
</buch>
</bibliothek>';
$doc = new DOMDocument();
$doc->loadXML($xml);
$xpath = new DOMXPath($doc);
$titel = $xpath->query('//buch/titel');
foreach ($titel as $node) {
echo $node->textContent . PHP_EOL;
}
/*
PHP Grundlagen
PHP Fortgeschritten
XML und XPath
*/
Zuerst wird das XML mit loadXML() in ein DOMDocument geladen. Anschließend wird ein DOMXPath Objekt erstellt, das die Methode query() bereitstellt. Der Ausdruck //buch/titel findet alle titel Elemente, die direkte Kinder eines buch Elements sind. Die zurückgegebene DOMNodeList lässt sich mit foreach durchlaufen, wobei textContent den Textinhalt jedes Knotens liefert.
Elemente nach Attribut filtern
Mit Prädikaten lassen sich Elemente anhand ihrer Attribute gezielt ansprechen. Das folgende Beispiel sucht ein Buch anhand seiner ISBN.
<?php
$doc = new DOMDocument();
$doc->loadXML($xml);
$xpath = new DOMXPath($doc);
/* Buch mit bestimmter ISBN suchen */
$ergebnis = $xpath->query('//buch[@isbn="978-3-456"]');
foreach ($ergebnis as $buch) {
$titel = $xpath->query('titel', $buch)->item(0)->textContent;
$autor = $xpath->query('autor', $buch)->item(0)->textContent;
echo $titel . ' von ' . $autor . PHP_EOL;
}
/*
PHP Fortgeschritten von Erika Musterfrau
*/
Der Ausdruck //buch[@isbn="978-3-456"] filtert nach dem Attributwert. Der zweite Parameter von query() erlaubt es, einen Kontextknoten anzugeben. So lassen sich relative Abfragen innerhalb eines gefundenen Elements ausführen.
XPath mit SimpleXML
Die Methode SimpleXMLElement::xpath() bietet eine einfachere Alternative zu DOMXPath. Sie gibt ein Array von SimpleXMLElement Objekten zurück und eignet sich gut für unkomplizierte XML Strukturen.
<?php
$xml = simplexml_load_string('<?xml version="1.0" encoding="UTF-8"?>
<bibliothek>
<buch isbn="978-3-123">
<titel>PHP Grundlagen</titel>
<autor>Max Mustermann</autor>
</buch>
<buch isbn="978-3-456">
<titel>PHP Fortgeschritten</titel>
<autor>Erika Musterfrau</autor>
</buch>
</bibliothek>');
$titel = $xml->xpath('//buch[@isbn="978-3-456"]/titel');
foreach ($titel as $element) {
echo (string) $element . PHP_EOL;
}
/*
PHP Fortgeschritten
*/
Im Vergleich zu DOMXPath entfällt hier das Erstellen eines separaten Abfrageobjekts. Die Methode xpath() wird direkt auf dem SimpleXMLElement aufgerufen. Wichtig ist, dass xpath() bei einem Fehler false zurückgibt und nicht ein leeres Array. Daher sollte das Ergebnis vor dem Durchlaufen geprüft werden. Für einfache Leseoperationen ist SimpleXML die schnellere Wahl. Sobald das Dokument verändert oder komplexere Abfragen benötigt werden, empfiehlt sich der Wechsel zu DOMXPath.
Namespaces in XPath Abfragen
XML Dokumente mit Namespaces erfordern einen zusätzlichen Schritt. Ohne die Registrierung des Namespaces liefern XPath Ausdrücke keine Ergebnisse, selbst wenn die Elementnamen korrekt sind.
<?php
$xmlMitNamespace = '<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
<title>Mein Blog</title>
<entry>
<title>Erster Beitrag</title>
<summary>Eine kurze Zusammenfassung</summary>
</entry>
<entry>
<title>Zweiter Beitrag</title>
<summary>Noch eine Zusammenfassung</summary>
</entry>
</feed>';
$doc = new DOMDocument();
$doc->loadXML($xmlMitNamespace);
$xpath = new DOMXPath($doc);
$xpath->registerNamespace('atom', 'http://www.w3.org/2005/Atom');
$eintraege = $xpath->query('//atom:entry/atom:title');
foreach ($eintraege as $eintrag) {
echo $eintrag->textContent . PHP_EOL;
}
/*
Erster Beitrag
Zweiter Beitrag
*/
Die Methode registerNamespace() ordnet einem Präfix den Namespace URI zu. In den XPath Ausdrücken wird dieses Präfix dann vor den Elementnamen gesetzt. Ohne diesen Schritt würde //entry/title bei einem Default Namespace keine Treffer liefern, da XPath Ausdrücke ohne Präfix nur Elemente ohne Namespace ansprechen.
HTML Dokumente mit XPath durchsuchen
XPath eignet sich nicht nur für XML, sondern auch für HTML Dokumente. Die Methode loadHTML() von DOMDocument lädt HTML und erzeugt daraus einen DOM Baum, der sich mit DOMXPath durchsuchen lässt.
<?php
$html = '<html>
<body>
<div class="content">
<a href="/seite1" class="highlight">Link 1</a>
<a href="/seite2">Link 2</a>
<a href="/seite3" class="highlight">Link 3</a>
</div>
</body>
</html>';
$doc = new DOMDocument();
libxml_use_internal_errors(true);
$doc->loadHTML($html);
libxml_clear_errors();
$xpath = new DOMXPath($doc);
$links = $xpath->query('//a[@class="highlight"]');
foreach ($links as $link) {
echo $link->getAttribute('href') . ' : ' . $link->textContent . PHP_EOL;
}
/*
/seite1 : Link 1
/seite3 : Link 3
*/
Da reales HTML oft nicht valide ist, gibt loadHTML() Warnungen aus. Mit libxml_use_internal_errors(true) werden diese Warnungen unterdrückt und stattdessen intern gespeichert. Der Aufruf von libxml_clear_errors() räumt den Fehlerspeicher anschließend auf. Dieser Ansatz ist besonders beim Web Scraping und bei der Analyse von HTML Fragmenten nützlich.
Fazit
XPath ist ein mächtiges Werkzeug zum gezielten Durchsuchen von XML und HTML Dokumenten in PHP. Die Klasse DOMXPath bietet maximale Kontrolle und eignet sich für komplexe Abfragen mit Kontextknoten und Namespace Registrierung. Die Methode SimpleXMLElement::xpath() ist die schlankere Alternative für einfache Leseoperationen. Beide Ansätze nutzen dieselbe XPath Syntax, unterscheiden sich jedoch in den Rückgabetypen: DOMNodeList bei DOMXPath und ein Array von SimpleXMLElement Objekten bei SimpleXML. Bei XML mit Default Namespace muss registerNamespace() zwingend aufgerufen werden, da XPath Ausdrücke ohne Präfix nur Elemente ohne Namespace finden. Für HTML Dokumente kombiniert man loadHTML() mit DOMXPath und nutzt libxml_use_internal_errors() zur sauberen Fehlerbehandlung.