W3docs

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
ParameterBeschreibung
$parserDer Parser, der mit xml_parser_create() erstellt wurde.
$start_handlerWird bei jedem öffnenden Tag aufgerufen. Erhält ($parser, $name, $attributes).
$end_handlerWird 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$name ist der Tag-Name und $attributes ist 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 als BOOK an). Vergleichen Sie Namen ohne Berücksichtigung der Groß-/Kleinschreibung, oder deaktivieren Sie die Umwandlung mit xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, false). Siehe xml_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:   LIBRARY

Beachten 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: 3

Wann 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.

Übungen

Übung
Wofür wird die Funktion xml_set_element_handler() in PHP verwendet?
Wofür wird die Funktion xml_set_element_handler() in PHP verwendet?
Was this page helpful?