Start · Sprachen · PHP · Referenz · xml_set_start_namespace_decl_handler

xml_set_start_namespace_decl_handler

Funktion

Registriert eine Callback-Funktion, die aufgerufen wird, wenn der XML-Parser eine öffnende Namespace-Deklaration (<code>xmlns:prefix="uri"</code>) erkennt.

seit PHP 4.0.5 Kategorie: xml

Signatur

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

Beschreibung

Mit xml_set_start_namespace_decl_handler() lässt sich ein Handler registrieren, der immer dann aufgerufen wird, wenn der XML-Parser den Beginn einer Namespace-Deklaration verarbeitet. Namespace-Deklarationen treten in XML-Dokumenten als Attribute der Form xmlns:prefix="namespaceURI" auf (bzw. als Standard-Namespace xmlns="...").

Der Handler erhält den Parser, das verwendete Präfix sowie die Namespace-URI übergeben. Dies ermöglicht es, Namespaces zur Laufzeit zu erfassen und beispielsweise eigene Namespace-Registries aufzubauen oder kontextsensitiv auf bestimmte XML-Vokabulare zu reagieren.

Die Funktion ist Teil der ereignisbasierten XML-Parser-Erweiterung (Expat). Sie wird meist in Kombination mit weiteren Handler-Funktionen wie xml_set_end_namespace_decl_handler() und xml_set_element_handler() verwendet, um vollständige Namespace-bewusste XML-Verarbeitung zu realisieren.

Wichtig: Die Funktion ist nur sinnvoll, wenn der Parser Namespace-Unterstützung aktiviert hat. Dies geschieht beim Erstellen des Parsers via xml_parser_create_ns(). Der Standard-Parser (xml_parser_create()) löst Namespace-Deklarationen nicht separat aus.

Parameter

Name Typ Default Beschreibung
$parser Pflicht XMLParser Eine gültige XMLParser-Instanz, die zuvor mit xml_parser_create_ns() erzeugt wurde.
$handler Pflicht callable Callback-Funktion mit der Signatur handler(XMLParser $parser, string $prefix, string $uri): void. $prefix enthält das Namespace-Präfix (oder einen leeren String beim Standard-Namespace), $uri die zugehörige Namespace-URI.

Rückgabewert

Typ
bool
Beschreibung
Gibt true zurück, wenn der Handler erfolgreich gesetzt wurde, andernfalls false (z. B. bei einem ungültigen Parser).

Beispiele

Namespace-Deklarationen in einem XML-Dokument erfassen

<?php
$xml = <<<XML
<?xml version="1.0" encoding="UTF-8"?>
<root xmlns:atom="http://www.w3.org/2005/Atom"
      xmlns:dc="http://purl.org/dc/elements/1.1/">
    <atom:entry>
        <dc:title>Beispiel</dc:title>
    </atom:entry>
</root>
XML;

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

$namespaces = [];

xml_set_start_namespace_decl_handler($parser, function (XMLParser $p, string $prefix, string $uri) use (&$namespaces) {
    $namespaces[$prefix] = $uri;
    echo "Namespace-Start: Präfix='" . ($prefix !== '' ? $prefix : '(Standard)') . "', URI='$uri'\n";
});

xml_set_element_handler(
    $parser,
    function (XMLParser $p, string $name, array $attrs) {},
    function (XMLParser $p, string $name) {}
);

if (!xml_parse($parser, $xml, true)) {
    echo 'Parse-Fehler: ' . xml_error_string(xml_get_error_code($parser));
}

xml_parser_free($parser);

echo "\nGefundene Namespaces:\n";
foreach ($namespaces as $prefix => $uri) {
    echo "  " . ($prefix !== '' ? $prefix : '(Standard)') . " => $uri\n";
}
Namespace-Start: Präfix='atom', URI='http://www.w3.org/2005/Atom' Namespace-Start: Präfix='dc', URI='http://purl.org/dc/elements/1.1/' Gefundene Namespaces: atom => http://www.w3.org/2005/Atom dc => http://purl.org/dc/elements/1.1/

Handler als Methode einer Klasse registrieren

<?php
class NsCollector {
    public array $found = [];

    public function onNsStart(XMLParser $parser, string $prefix, string $uri): void {
        $this->found[] = ['prefix' => $prefix, 'uri' => $uri];
    }
}

$xml = '<doc xmlns:foo="urn:foo" xmlns="urn:default"><foo:bar/></doc>';

$parser = xml_parser_create_ns('UTF-8');
$collector = new NsCollector();

xml_set_object($parser, $collector);
xml_set_start_namespace_decl_handler($parser, 'onNsStart');
xml_set_element_handler($parser, function () {}, function () {});

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

var_dump($collector->found);
array(2) { [0]=> array(2) { ["prefix"]=> string(3) "foo" ["uri"]=> string(7) "urn:foo" } [1]=> array(2) { ["prefix"]=> string(0) "" ["uri"]=> string(11) "urn:default" } }

// Wichtig · Fallstricke

Namespace-Parser erforderlich: Der Handler wird nur ausgelöst, wenn der Parser mit xml_parser_create_ns() erstellt wurde. Bei Verwendung von xml_parser_create() werden Namespace-Deklarationen nicht gesondert gemeldet.

Reihenfolge der Aufrufe: Der Start-Namespace-Handler wird vor dem zugehörigen Element-Start-Handler aufgerufen. Ebenso wird der End-Namespace-Handler nach dem End-Element-Handler ausgelöst.

Standard-Namespace: Beim Standardnamespace (xmlns="...") wird $prefix als leerer String übergeben. Prüfe daher stets auf leeren String, nicht nur auf null.

Ab PHP 8.0 ist der erste Parameter vom Typ XMLParser (Objekt) statt resource.