W3docs

xpath()

SimpleXMLElement::xpath() führt XPath-Abfragen auf XML-Dokumenten in PHP aus und gibt passende Knoten zurück.

Einführung

SimpleXMLElement::xpath() führt eine XPath-Abfrage auf einem XML-Dokument aus, das mit der PHP-Erweiterung SimpleXML geladen wurde, und gibt die übereinstimmenden Knoten zurück. Ohne diese Funktion kann man einen XML-Baum nur Eigenschaft für Eigenschaft durchlaufen ($xml->book->title); mit ihr kann man mit einem einzigen Pfadausdruck wie //book/title direkt zu jedem Knoten springen — egal wie tief er liegt.

Diese Seite erklärt, was xpath() zurückgibt, die am häufigsten verwendete XPath-Syntax, wie man Attribute liest und Namespaces behandelt, sowie typische Fallstricke.

Syntax

public SimpleXMLElement::xpath(string $expression): array|false
  • $expression — der auszuwertende XPath-Ausdruck, relativ zum Knoten, auf dem er aufgerufen wird.
  • Gibt zurück — ein Array von SimpleXMLElement-Objekten für jeden übereinstimmenden Knoten, ein leeres Array, wenn nichts übereinstimmt, oder false bei einem fehlerhaften Ausdruck.

Da das Ergebnis immer ein Array ist, wird es üblicherweise mit foreach iteriert, auch wenn nur eine Übereinstimmung erwartet wird.

Ein erstes Beispiel

Die folgenden Beispiele verwenden simplexml_load_string(), sodass sie ohne externe Datei direkt ausgeführt werden können:

<?php

$data = <<<XML
<library>
    <book genre="fiction">
        <title>The Pragmatic Programmer</title>
        <author>Hunt</author>
    </book>
    <book genre="reference">
        <title>PHP Cookbook</title>
        <author>Sklar</author>
    </book>
</library>
XML;

$xml = simplexml_load_string($data);

// Select every <title> anywhere under the root.
foreach ($xml->xpath('//title') as $title) {
    echo $title . "\n";
}

Ausgabe:

The Pragmatic Programmer
PHP Cookbook

//title bedeutet "jedes title-Element auf beliebiger Tiefe." Die Schleife gibt jedes Ergebnis aus; die Umwandlung eines SimpleXMLElement in einen string (durch echo implizit vorgenommen) liefert seinen Textinhalt.

Häufige XPath-Ausdrücke

AusdruckWählt aus
/library/bookbook-Elemente, die direkte Kinder des Wurzelelements library sind
//bookjedes book-Element, auf beliebiger Tiefe
//book/titledas title-Kindelement jedes book
//book[1]das erste book (XPath ist 1-indiziert, nicht 0)
//book[@genre='fiction']Bücher, deren genre-Attribut gleich fiction ist
//book[author='Sklar']Bücher mit einem <author>-Kindelement mit dem Wert Sklar
//@genrejeder genre-Attributknoten

Filtern mit einem Prädikat

Ein Prädikat in eckigen Klammern behält nur die Knoten, die einer Bedingung entsprechen:

<?php

$data = <<<XML
<library>
    <book genre="fiction"><title>Dune</title></book>
    <book genre="reference"><title>PHP Cookbook</title></book>
</library>
XML;

$xml = simplexml_load_string($data);

$fiction = $xml->xpath("//book[@genre='fiction']");
echo $fiction[0]->title . "\n";  // Dune
echo count($fiction) . " match\n"; // 1 match

Ausgabe:

Dune
1 match

Das Lesen eines Attributs innerhalb des Prädikats verwendet @, während das Lesen aus einem Ergebnisknoten die Array-Syntax verwendet — (string) $book['genre']. Weitere Einzelheiten finden Sie unter attributes.

Arbeiten mit XML-Namespaces

Wenn das Dokument Namespaces deklariert, gibt ein einfacher Pfad wie //book nichts zurück — der Parser benötigt das Namespace-Präfix. Registrieren Sie zuerst ein Präfix mit registerXPathNamespace() und verwenden Sie es dann im Ausdruck:

<?php

$data = <<<XML
<lib:library xmlns:lib="http://example.com/lib">
    <lib:book><lib:title>Clean Code</lib:title></lib:book>
</lib:library>
XML;

$xml = simplexml_load_string($data);
$xml->registerXPathNamespace('l', 'http://example.com/lib');

foreach ($xml->xpath('//l:book/l:title') as $title) {
    echo $title . "\n";  // Clean Code
}

Ausgabe:

Clean Code

Das von Ihnen registrierte Präfix (l) ist lokal für Ihre Abfrage — es muss nicht mit dem im Dokument verwendeten Präfix (lib) übereinstimmen; nur der Namespace-URI muss übereinstimmen.

Fallstricke

  • Ergebnis immer prüfen. xpath() gibt bei einem ungültigen Ausdruck false zurück und bei keiner Übereinstimmung ein leeres Array. foreach (($xml->xpath($e) ?: []) as $n) schützt vor beidem.
  • Ergebnisse sind Objekte, keine Strings. Mit (string) umwandeln, wenn der Text benötigt wird: (string) $node.
  • XPath indiziert ab 1. //book[1] ist das erste Buch; es gibt kein [0].
  • Kontext ist wichtig. Das Aufrufen von xpath('title') auf einem book-Knoten sucht relativ zu diesem Knoten, während ein führendes / oder // unabhängig vom Aufrufkontext immer vom Dokumentwurzel aus sucht.

Fazit

SimpleXMLElement::xpath() verwandelt tiefes, wiederholendes Baumdurchlaufen in eine einzige deklarative Abfrage. In Kombination mit Prädikaten und Namespace-Registrierung ermöglicht es, genau die benötigten Knoten zu finden. Kombinieren Sie es mit simplexml_load_string() oder der umfassenderen SimpleXML-API, um XML in nur wenigen Zeilen zu lesen und zu transformieren.

Übungen

Übung
Wofür wird XPath in PHP verwendet?
Wofür wird XPath in PHP verwendet?
Was this page helpful?