Start · Sprachen · PHP · Referenz · xml_set_end_namespace_decl_handler

xml_set_end_namespace_decl_handler

Funktion

Registriert einen Callback-Handler, der aufgerufen wird, wenn eine Namespace-Deklaration in einem XML-Dokument endet.

seit PHP 5.0.0 Kategorie: xml

Signatur

xml_set_end_namespace_decl_handler(XMLParser $parser, callable $handler): bool

Beschreibung

xml_set_end_namespace_decl_handler() legt einen Handler fest, der immer dann aufgerufen wird, wenn der XML-Parser das Ende eines Namespace-Gültigkeitsbereichs erkennt. Ein Namespace-Gültigkeitsbereich beginnt mit dem öffnenden Tag, das die xmlns-Deklaration enthält, und endet mit dem entsprechenden schließenden Tag.

Der Handler ergänzt xml_set_start_namespace_decl_handler() und ermöglicht es, auf das Ende eines Namespace-Kontexts zu reagieren – beispielsweise um eigene Namespace-Stapel oder Mappings zu bereinigen. Der registrierte Callback wird mit dem Parser-Handle und dem Namespace-Präfix als Argumente aufgerufen.

Diese Funktion ist vor allem nützlich, wenn Namespace-sensible XML-Dokumente (z. B. SOAP- oder SVG-Dateien) verarbeitet werden und der Lebenszyklus einzelner Namespace-Deklarationen präzise nachverfolgt werden soll. Sie wird typischerweise zusammen mit dem expat-basierten XML-Parser von PHP verwendet.

Zu beachten ist, dass der End-Namespace-Handler nach dem End-Element-Handler für das entsprechende Element aufgerufen wird, sodass das Element selbst bereits vollständig verarbeitet ist, wenn der Namespace-Kontext geschlossen wird.

Parameter

Name Typ Default Beschreibung
$parser Pflicht XMLParser Die XML-Parser-Ressource (ab PHP 8.0 ein XMLParser-Objekt), die mit xml_parser_create_ns() erstellt wurde.
$handler Pflicht callable Der Callback, der beim Ende einer Namespace-Deklaration aufgerufen wird. Er muss die Signatur handler(XMLParser $parser, string $prefix): void haben. $prefix ist das Namespace-Präfix (oder ein leerer String für den Standard-Namespace).

Rückgabewert

Typ
bool
Beschreibung
Gibt true zurück, wenn der Handler erfolgreich registriert wurde, andernfalls false.

Beispiele

Namespace-Lebenszyklus verfolgen

<?php
$xml = <<<XML
<?xml version="1.0"?>
<root xmlns:foo="http://example.com/foo" xmlns:bar="http://example.com/bar">
    <foo:child>Inhalt</foo:child>
    <bar:item>Wert</bar:item>
</root>
XML;

$parser = xml_parser_create_ns('UTF-8');

xml_set_start_namespace_decl_handler($parser, function ($parser, $prefix, $uri) {
    echo "Namespace gestartet: Präfix='{$prefix}', URI='{$uri}'" . PHP_EOL;
});

xml_set_end_namespace_decl_handler($parser, function ($parser, $prefix) {
    echo "Namespace beendet: Präfix='{$prefix}'" . PHP_EOL;
});

xml_parse($parser, $xml, true);
xml_parser_free($parser);
Namespace gestartet: Präfix='foo', URI='http://example.com/foo' Namespace gestartet: Präfix='bar', URI='http://example.com/bar' Namespace beendet: Präfix='foo' Namespace beendet: Präfix='bar'

Namespace-Stapel mit Start- und End-Handler verwalten

<?php
$xml = <<<XML
<?xml version="1.0"?>
<doc xmlns:ns="http://example.com/ns">
    <ns:section xmlns:inner="http://example.com/inner">
        <inner:item>Test</inner:item>
    </ns:section>
</doc>
XML;

$namespaceStack = [];

$parser = xml_parser_create_ns('UTF-8');

xml_set_start_namespace_decl_handler($parser, function ($parser, $prefix, $uri) use (&$namespaceStack) {
    $namespaceStack[] = $prefix;
    echo "+ Namespace '{$prefix}' aktiv. Stapel: " . implode(', ', $namespaceStack) . PHP_EOL;
});

xml_set_end_namespace_decl_handler($parser, function ($parser, $prefix) use (&$namespaceStack) {
    $namespaceStack = array_filter($namespaceStack, fn($p) => $p !== $prefix);
    echo "- Namespace '{$prefix}' entfernt. Stapel: " . implode(', ', $namespaceStack) . PHP_EOL;
});

xml_parse($parser, $xml, true);
xml_parser_free($parser);
+ Namespace 'ns' aktiv. Stapel: ns + Namespace 'inner' aktiv. Stapel: ns, inner - Namespace 'inner' entfernt. Stapel: ns - Namespace 'ns' entfernt. Stapel:

// Wichtig · Fallstricke

Wichtig: Diese Funktion funktioniert nur, wenn der Parser mit xml_parser_create_ns() erstellt wurde, da nur dieser Namespace-Verarbeitung unterstützt. Bei einem mit xml_parser_create() erzeugten Parser wird der Handler ignoriert.

Der End-Namespace-Handler wird nach dem End-Element-Handler aufgerufen. Das bedeutet, dass beim Aufruf das entsprechende Element bereits abgeschlossen ist. Beim Start-Namespace-Handler ist es umgekehrt: er wird vor dem Start-Element-Handler aufgerufen.

Ab PHP 8.0 wurde der Rückgabetyp des Parsers von einer Ressource (resource) auf ein Objekt vom Typ XMLParser geändert. Bestehender Code, der is_resource() zur Überprüfung verwendet, muss entsprechend angepasst werden.