W3docs

xml_set_end_namespace_decl_handler()

Die Funktion xml_set_end_namespace_decl_handler() setzt eine benutzerdefinierte Funktion als Handler für das Ende von Namespace-Deklarationen in PHP.

Die Funktion xml_set_end_namespace_decl_handler() ist eine in PHP integrierte Funktion, die einen benutzerdefinierten Callback registriert, der ausgeführt wird, sobald der SAX-XML-Parser das Ende eines Elements erreicht, das einen oder mehrere XML-Namespaces deklariert hat. Sie ist das schließende Gegenstück zu xml_set_start_namespace_decl_handler(): Der Start-Handler wird ausgelöst, wenn ein Namespace-Präfix in den Gültigkeitsbereich eintritt, und dieser End-Handler wird ausgelöst, wenn das Präfix den Gültigkeitsbereich wieder verlässt.

Diese Funktion gehört zu PHPs ereignisgesteuerter (SAX) xml-Erweiterung, die ein Dokument von oben nach unten liest und Ihre Handler aufruft, sobald sie auf ein Konstrukt trifft – anstatt wie SimpleXML einen Baum im Speicher aufzubauen. Sie ist am nützlichsten, wenn Sie verfolgen möchten, welche Namespaces beim Parsen gerade aktiv sind – beispielsweise um einen Stack der aktiven Präfixe zu verwalten oder den Zustand zu bereinigen, sobald ein mit einem Namespace versehener Abschnitt endet.

Verwendungszweck

Eine Namespace-Deklaration ist ein Attribut wie xmlns:ns="http://example.com". Ihr Gültigkeitsbereich erstreckt sich auf das Element, auf dem sie erscheint, sowie auf alle Nachfahren dieses Elements. Verwenden Sie den End-Namespace-Handler, wenn Sie den genauen Moment wissen müssen, in dem dieser Gültigkeitsbereich endet – typischerweise um ein Präfix von einem Stack zu entfernen, den Sie im Start-Handler aufgebaut haben, und dabei die Bereichsverwaltung des Parsers zu spiegeln.

Syntax

xml_set_end_namespace_decl_handler(XMLParser $parser, callable|false $handler): bool
ParameterBeschreibung
$parserDer XML-Parser, erstellt mit xml_parser_create_ns() (empfohlen) oder xml_parser_create().
$handlerDer Callback, der bei jedem End-of-Namespace-Ereignis ausgeführt wird, oder false um einen zuvor gesetzten Handler zu entfernen.

Rückgabewert: Gibt bei Erfolg true und bei Misserfolg false zurück (zum Beispiel wenn $parser kein gültiger Parser ist).

Ihr Handler erhält zwei Argumente:

function handler(XMLParser $parser, string $prefix): void

$prefix ist das Namespace-Präfix, dessen Gültigkeitsbereich endet (ein leerer string "" bei einer Standard-xmlns="..."-Deklaration). Beachten Sie, dass der End-Handler im Gegensatz zum Start-Handler nicht den Namespace-URI erhält – nur das Präfix.

Verwendungsbeispiele

Beispiel: Einen End-Namespace-Deklarations-Handler setzen

Dieses Beispiel richtet den Handler ein und löst ihn durch das Parsen eines kleinen XML-Strings aus. Der Handler wird während xml_parse() aufgerufen, wenn der Parser das Element schließt, das den Namespace deklariert hat.

XML mit einem End-Namespace-Deklarations-Handler parsen

function handle_end_namespace_decl($parser, $prefix) {
    echo "End of namespace prefix: $prefix\n";
}

$xml_parser = xml_parser_create_ns();
xml_set_end_namespace_decl_handler($xml_parser, "handle_end_namespace_decl");

$xml_data = '<?xml version="1.0"?><root xmlns:ns="http://example.com"><ns:child/></root>';
xml_parse($xml_parser, $xml_data, true);
xml_parser_free($xml_parser);

Das Präfix ns wird auf <root> deklariert, daher endet sein Gültigkeitsbereich, wenn </root> erreicht wird. Wenn der Handler ausgelöst wird, gibt er das Präfix aus, das den Gültigkeitsbereich verlässt:

End of namespace prefix: ns

Hinweis: Das Auslösen des End-Namespace-Handlers hängt vom zugrunde liegenden libexpat/PHP-Build ab – bei manchen PHP-Versionen wird der Start-Handler ausgeführt, der End-Handler jedoch nicht. Testen Sie stets gegen Ihre Zielumgebung und verlassen Sie sich nie allein auf den End-Handler, um einen Namespace zu erkennen; kombinieren Sie ihn mit dem Start-Handler (siehe unten), damit Ihr Zustand konsistent bleibt.

Beispiel: Start- und End-Handler kombinieren, um den Gültigkeitsbereich zu verfolgen

In echten Parsern wird der End-Handler selten allein verwendet. Wenn Sie ihn mit dem Start-Handler kombinieren, können Sie einen Stack der aktuell gültigen Präfixe verwalten. Der Start-Handler legt jedes Präfix auf den Stack, wenn es in den Gültigkeitsbereich tritt; der End-Handler entfernt es, wenn das deklarierende Element geschlossen wird:

Aktive Namespace-Präfixe mit einem Stack verfolgen

$activePrefixes = [];

function on_start_ns($parser, $prefix, $uri) {
    global $activePrefixes;
    $activePrefixes[] = $prefix;
    echo "Enter '$prefix' -> $uri | active: " . implode(', ', $activePrefixes) . "\n";
}

function on_end_ns($parser, $prefix) {
    global $activePrefixes;
    array_pop($activePrefixes);
    echo "Leave '$prefix' | active: " . implode(', ', $activePrefixes) . "\n";
}

$parser = xml_parser_create_ns();
xml_set_start_namespace_decl_handler($parser, "on_start_ns");
xml_set_end_namespace_decl_handler($parser, "on_end_ns");

$xml = '<?xml version="1.0"?>'
     . '<a xmlns:x="urn:x"><b xmlns:y="urn:y"><c/></b></a>';

xml_parse($parser, $xml, true);
xml_parser_free($parser);

Das Präfix x wird auf <a> deklariert und y auf dem inneren <b>. Wenn sich Gültigkeitsbereiche öffnen und schließen, verfolgt der Stack, welche Präfixe gerade aktiv sind. Die End-Ereignisse werden in der Last-in-first-out-Reihenfolge ausgelöst – y (das innere) verlässt den Gültigkeitsbereich vor x:

Enter 'x' -> urn:x | active: x
Enter 'y' -> urn:y | active: x, y
Leave 'y' | active: x
Leave 'x' | active: 

Dieses Start/Pop-Muster ist die kanonische Verwendung des End-Handlers: Es hält Ihre Sicht auf die aktiven Namespaces mit der eigenen Bereichsverwaltung des Parsers synchron.

Häufige Fallstricke

  • Verwenden Sie xml_parser_create_ns(). Namespace-Handler erhalten nur dann Ereignisse, wenn der Parser Namespace-fähig ist. Ein Parser, der mit dem einfachen xml_parser_create() erstellt wurde, trennt Präfixe nicht von URIs.
  • Kein URI im End-Callback. Wenn Sie den URI beim Schließen des Gültigkeitsbereichs benötigen, erfassen Sie ihn im Start-Handler (nach Präfix indiziert) und schlagen Sie ihn hier nach.
  • Handler vor dem Parsen setzen. Registrieren Sie den Handler, bevor Sie xml_parse() zum ersten Mal aufrufen; Handler, die mitten im Parsen gesetzt werden, verpassen frühere Ereignisse.
  • Parser freigeben. Rufen Sie xml_parser_free() auf, wenn Sie fertig sind, um Ressourcen freizugeben – besonders in lang laufenden Skripten.

Fazit

xml_set_end_namespace_decl_handler() ermöglicht es einem SAX-Parser, Ihrem Code genau mitzuteilen, wann ein XML-Namespace-Präfix den Gültigkeitsbereich verlässt. In Kombination mit xml_set_start_namespace_decl_handler() und einem Namespace-fähigen Parser aus xml_parser_create_ns() erhalten Sie präzise, speichereffiziente Kontrolle über den Namespace-Bereich beim Streaming durch große XML-Dokumente.

Übungen

Übung
Was ist die Funktion von xml_set_end_namespace_decl_handler() in PHP?
Was ist die Funktion von xml_set_end_namespace_decl_handler() in PHP?
Was this page helpful?