xml_set_element_handler()
Die Funktion xml_set_element_handler() registriert benutzerdefinierte Handler-Funktionen für Start- und End-Tags eines XML-Elements in PHP.
xml_set_element_handler() registriert zwei Callbacks an einem XML-Parser: einen, der jedes Mal ausgelöst wird, wenn der Parser ein öffnendes Tag (<book>) findet, und einen, der bei jedem schließenden Tag (</book>) aufgerufen wird. Die Funktion gehört zu PHPs ereignisbasiertem Expat-Parser — der xml_parser_*-Familie — und nicht zu SimpleXML oder DOM. Während SimpleXML das gesamte Dokument als Baum im Speicher lädt, verarbeitet Expat das Dokument als Stream und ruft die Handler beim Durchlaufen auf, was es besonders geeignet für große Dateien macht, die man nicht vollständig laden möchte.
Diese Seite behandelt die Signatur der Funktion, die genauen Argumente, die Ihre Handler empfangen, ein vollständiges, ausführbares Beispiel sowie häufige Fallstricke (Groß-/Kleinschreibung von Tag-Namen und die Callback-Form für Objektmethoden).
Syntax
xml_set_element_handler(
XMLParser $parser,
callable $start_handler,
callable $end_handler
): bool| Parameter | Beschreibung |
|---|---|
$parser | Der Parser, der mit xml_parser_create() erstellt wurde. |
$start_handler | Wird bei jedem öffnenden Tag aufgerufen. Erhält ($parser, $name, $attributes). |
$end_handler | Wird bei jedem schließenden Tag aufgerufen. Erhält ($parser, $name). |
Die Funktion gibt bei Erfolg true und bei Fehler false zurück. Ein Callback kann als Funktionsname-String ("startTag"), als Closure oder als Objekt-Methoden-Paar ([$object, 'method']) übergeben werden.
Was die Handler empfangen
- Start-Handler —
$nameist der Tag-Name und$attributesist ein assoziatives Array der Attribute dieses Tags (['ID' => 'b1']). - End-Handler — nur
$name, da schließende Tags keine Attribute haben.
Standardmäßig wandelt Expat Tag- und Attributnamen in Großbuchstaben um (
<book>kommt alsBOOKan). Vergleichen Sie Namen ohne Berücksichtigung der Groß-/Kleinschreibung, oder deaktivieren Sie die Umwandlung mitxml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, false). Siehexml_parser_set_option().
Verwendungsbeispiele
Beispiel: Den Elementbaum ausgeben
Dieses vollständige Skript parst einen XML-String und verwendet Start-/End-Handler, um eine eingerückte Übersicht des Dokuments auszugeben, einschließlich der Attribute jedes Tags.
<?php
$xml = '<?xml version="1.0"?>
<library>
<book id="b1">PHP Basics</book>
<book id="b2">Advanced XML</book>
</library>';
$depth = 0;
function startTag($parser, $name, $attrs) {
global $depth;
echo str_repeat(" ", $depth) . "START: $name";
foreach ($attrs as $key => $value) {
echo " ($key=\"$value\")";
}
echo "\n";
$depth++;
}
function endTag($parser, $name) {
global $depth;
$depth--;
echo str_repeat(" ", $depth) . "END: $name\n";
}
$parser = xml_parser_create();
xml_set_element_handler($parser, "startTag", "endTag");
if (!xml_parse($parser, $xml, true)) {
die(sprintf(
"XML error: %s at line %d",
xml_error_string(xml_get_error_code($parser)),
xml_get_current_line_number($parser)
));
}
xml_parser_free($parser);Ausgabe:
START: LIBRARY
START: BOOK (ID="b1")
END: BOOK
START: BOOK (ID="b2")
END: BOOK
END: LIBRARYBeachten Sie, dass library als LIBRARY und id als ID ankommt: Das ist die oben erwähnte Groß-/Kleinschreibungsumwandlung. Das dritte Argument für xml_parse() ist auf true gesetzt, um dem Parser mitzuteilen, dass dies der letzte (und einzige) Datenblock ist. Geben Sie den Parser nach der Verwendung immer mit xml_parser_free() frei.
Beispiel: Eine Objektmethode als Handler verwenden
Handler müssen keine freien Funktionen sein. Die Übergabe von [$object, 'method'] ermöglicht es, den Parsing-Zustand auf einem Objekt statt in globalen Variablen zu speichern — nützlich, wenn mehrere Handler Daten teilen müssen.
<?php
$xml = '<note><to>Tove</to><from>Jani</from></note>';
class TagCounter {
public int $open = 0;
public function onStart($parser, $name, $attrs) { $this->open++; }
public function onEnd($parser, $name) {}
}
$counter = new TagCounter();
$parser = xml_parser_create();
xml_set_element_handler($parser, [$counter, 'onStart'], [$counter, 'onEnd']);
xml_parse($parser, $xml, true);
xml_parser_free($parser);
echo "Opening tags seen: {$counter->open}\n";Ausgabe:
Opening tags seen: 3Wann man es verwenden sollte
Verwenden Sie die Expat-Handler, wenn Sie einen streamingbasierten, speicherschonenden Durchlauf über XML benötigen — bei großen Feeds, Log-Dateien oder Sitemaps — oder wenn Sie nur an wenigen Tags interessiert sind und keinen vollständigen Baum aufbauen möchten. Um den Text innerhalb eines Elements zu lesen (das PHP Basics in <book>PHP Basics</book>), kombinieren Sie dies mit xml_set_character_data_handler(). Wenn Sie lieber ein kleines Dokument mit XPath-ähnlichem Zugriff abfragen möchten, ist SimpleXML einfacher. Einen Überblick über alle Ansätze finden Sie unter PHP XML Parsers.
Fazit
xml_set_element_handler() bindet Start- und End-Tag-Callbacks in PHPs ereignisgesteuerten Expat-Parser ein und ermöglicht es Ihnen, auf die Struktur eines Dokuments zu reagieren, während es gestreamt wird. Merken Sie sich die drei wesentlichen Punkte: zuerst den Parser erstellen, die Großschreibung von Tag-Namen berücksichtigen und den Parser nach der Verwendung freigeben.