W3docs

xml_parse()

Die Funktion xml_parse() ist eine eingebaute PHP-Funktion zum Parsen von XML-Daten mit dem SAX-Parser-Ansatz.

Was ist xml_parse()?

Die Funktion xml_parse() ist eine eingebaute PHP-Funktion zum Parsen von XML-Daten. Sie gehört zur PHP-XML-Parser-Erweiterung und implementiert einen SAX-basierten (Simple API for XML) Streaming-Parser. Im Gegensatz zu baumbasierten Parsern verarbeitet sie XML sequenziell und löst Callback-Funktionen aus, sobald Elemente, Attribute und Zeichendaten auftreten. Dadurch ist sie sehr effizient beim Parsen großer XML-Dateien, ohne das gesamte Dokument in den Speicher laden zu müssen.

Die Funktion xml_parse() ist nützlich, wenn Sie XML-Daten in PHP verarbeiten müssen, zum Beispiel um Daten aus einer XML-Datei zu extrahieren, XML-Daten in ein anderes Format zu transformieren oder XML-Streams in Echtzeit zu verarbeiten.

Syntax

Die Syntax der Funktion xml_parse() lautet wie folgt:

xml_parse($parser, $data, $is_final = false): int

Parameter

  • $parser — das XML-Parser-Handle, das von xml_parser_create() zurückgegeben wird. Dies ist das Objekt, das den Parsing-Zustand enthält.
  • $data — ein Teil (oder der gesamte) XML-Text, der dem Parser übergeben wird.
  • $is_final — auf true setzen, wenn Sie den letzten Datenteil übergeben. Solange dieser Wert false ist, behält der Parser seinen Zustand, sodass Sie xml_parse() erneut mit dem nächsten Teil aufrufen können.

Rückgabewert

xml_parse() gibt bei Erfolg 1 (truthy) und bei Fehler 0 (falsy) zurück. Die Funktion gibt nicht die geparsten Daten zurück — der geparste Inhalt wird an die registrierten Handler-Callbacks übergeben. Wenn 0 zurückgegeben wird, können Sie den Fehler mit xml_get_error_code() und xml_error_string() untersuchen.

Verwendungsbeispiele

Schauen wir uns einige praktische Beispiele zur Verwendung von xml_parse() in PHP an.

Beispiel 1: XML mit Event-Handlern parsen

xml_parse() ist ein SAX-Parser: Er erstellt kein Dokument für Sie, er löst Ereignisse aus. Um eine Ausgabe zu erhalten, müssen Sie Handler-Funktionen registrieren. Das folgende Beispiel verwendet einen eingebetteten XML-String, sodass es ohne externe Datei direkt ausgeführt werden kann:

<?php
$xml = <<<XML
<?xml version="1.0"?>
<note>
  <to>Tove</to>
  <from>Jani</from>
</note>
XML;

$parser = xml_parser_create();
// Keep element names in their original case instead of upper-casing them.
xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, 0);

xml_set_element_handler(
    $parser,
    fn($p, $name, $attrs) => print("Start: $name\n"),
    fn($p, $name)         => print("End:   $name\n")
);
xml_set_character_data_handler($parser, function ($p, $data) {
    $data = trim($data);
    if ($data !== "") {
        echo "Text:  $data\n";
    }
});

if (!xml_parse($parser, $xml, true)) {
    $code = xml_get_error_code($parser);
    echo "Error: " . xml_error_string($code)
       . " at line " . xml_get_current_line_number($parser);
}

xml_parser_free($parser);

Dies gibt aus:

Start: note
Start: to
Text:  Tove
End:   to
Start: from
Text:  Jani
End:   from
End:   note

Der Parser durchläuft das Dokument von oben nach unten und ruft Ihre Start-Element-, Zeichendaten- und End-Element-Handler in der Dokumentreihenfolge auf. Wir registrieren sie mit xml_set_element_handler() und xml_set_character_data_handler(), übergeben alles in einem Aufruf ($is_final = true) und geben den Parser mit xml_parser_free() frei.

Beispiel 2: Datei oder Datenstrom in Teilen parsen

Die eigentliche Stärke von xml_parse() liegt im inkrementellen Parsen: Das Dokument wird stückweise eingespeist, sodass selbst eine mehrere Gigabyte große Datei nicht in den Speicher passen muss. Übergeben Sie $is_final = false für jeden Teil außer dem letzten:

<?php
$parser = xml_parser_create();
xml_set_element_handler(
    $parser,
    fn($p, $name, $attrs) => print("<$name>\n"),
    fn($p, $name)         => print("</$name>\n")
);

$handle = fopen("data.xml", "r");          // or php://stdin for a stream
while (($chunk = fread($handle, 4096)) !== false) {
    $isFinal = feof($handle);
    if (!xml_parse($parser, $chunk, $isFinal)) {
        $code = xml_get_error_code($parser);
        echo "XML error: " . xml_error_string($code)
           . " at line " . xml_get_current_line_number($parser);
        break;
    }
    if ($isFinal) {
        break;
    }
}
fclose($handle);
xml_parser_free($parser);

Da der Parser seinen Zustand zwischen den Aufrufen beibehält, kann ein Element in einem Teil beginnen und in einem anderen enden — xml_parse() fügt die Ereignisse korrekt zusammen. Genau das macht die Funktion für große XML-Dateien geeignet, bei denen ein baumbasierter Ansatz wie SimpleXML den Speicher erschöpfen würde.

Beispiel 3 (Referenz): Eine Datei in einem Schritt parsen

Wenn Ihr XML klein genug ist, um in den Speicher zu passen, können Sie es mit file_get_contents() lesen und den gesamten String in einem einzigen Aufruf an xml_parse() übergeben. Handler können auch benannte Funktionen (als Strings) anstelle von Closures sein:

$xml_parser = xml_parser_create();
xml_parser_set_option($xml_parser, XML_OPTION_CASE_FOLDING, 0);

// Define handler functions
function startElement($parser, $name, $attrs) {
    echo "Start element: $name\n";
}
function endElement($parser, $name) {
    echo "End element: $name\n";
}
function characterData($parser, $data) {
    echo "Data: $data\n";
}

// Set handlers
xml_set_element_handler($xml_parser, "startElement", "endElement");
xml_set_character_data_handler($xml_parser, "characterData");

$xml_data = file_get_contents("data.xml");
if (!xml_parse($xml_parser, $xml_data, true)) {
    $error_message = xml_error_string(xml_get_error_code($xml_parser));
    $error_line = xml_get_current_line_number($xml_parser);
    echo "XML Parsing Error: $error_message at line $error_line";
}
xml_parser_free($xml_parser);

Dieser Code erstellt einen XML-Parser mit xml_parser_create() und deaktiviert die Groß-/Kleinschreibungskonvertierung. Anschließend werden drei Callback-Funktionen definiert: startElement() für öffnende Tags, endElement() für schließende Tags und characterData() für Textinhalte. Diese Handler werden mit xml_set_element_handler() und xml_set_character_data_handler() registriert.

Das Skript liest „data.xml" und übergibt den Inhalt an xml_parse(). Während der Parser durch das XML streamt, ruft er automatisch die registrierten Handler auf. Tritt beim Parsen ein Fehler auf, werden der Fehlercode und die Fehlermeldung mit xml_get_error_code() und xml_error_string() abgerufen und eine beschreibende Fehlermeldung ausgegeben. Abschließend wird der Parser-Speicher mit xml_parser_free() freigegeben.

Häufige Fallstricke

  • Keine Handler, keine Ausgabe. xml_parse() löst nur die von Ihnen registrierten Callbacks aus. Wenn keine Handler gesetzt sind, wird erfolgreich geparst, aber nichts sichtbares ausgegeben.
  • Zeichendaten kommen stückweise an. Ein einzelner Textknoten kann xml_set_character_data_handler mehrfach auslösen (z. B. rund um Entity-Referenzen). Akkumulieren Sie den Text daher in einem Puffer, anstatt anzunehmen, dass Sie ihn auf einmal erhalten.
  • Leerzeichen zählen als Zeichendaten. Einrückungen zwischen Tags lösen den Zeichendaten-Handler aus. Verwenden Sie trim() (wie in Beispiel 1), wenn Sie nur echten Text benötigen.
  • Den Parser immer freigeben. Rufen Sie xml_parser_free() auf, wenn Sie fertig sind. In PHP 8+ ist das Handle ein XMLParser-Objekt, das durch den Garbage Collector freigegeben wird, aber explizites Freigeben hält den Speicherbedarf bei langlebigen Skripten gering.

Verwandte Funktionen

Fazit

PHPs Funktion xml_parse() ist der Motor der SAX-basierten XML-Parser-Erweiterung. Anstatt ein Dokument zurückzugeben, streamt sie durch XML und löst die von Ihnen registrierten Handler aus, wobei sie bei Erfolg 1 und bei Fehler 0 zurückgibt. Der Parameter $is_final ermöglicht das Parsen von Daten in Teilen, was die Funktion auch bei sehr großen Dateien speichereffizient macht. In Kombination mit xml_parser_create(), den Handler-Setup-Funktionen und xml_parser_free() ergibt sich eine schnelle und speicherschonende Methode zur XML-Verarbeitung in PHP.

Übung

Übung
Was ist XML Parser in PHP?
Was ist XML Parser in PHP?
Was this page helpful?