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| Parameter | Beschreibung |
|---|---|
$parser | Der XML-Parser, erstellt mit xml_parser_create_ns() (empfohlen) oder xml_parser_create(). |
$handler | Der 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: nsHinweis: 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 einfachenxml_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.