xml_set_start_namespace_decl_handler()
La funzione xml_set_start_namespace_decl_handler() imposta una funzione definita dall'utente come gestore per le dichiarazioni di namespace iniziali
La funzione xml_set_start_namespace_decl_handler() registra un callback che il parser XML richiama ogni volta che incontra l'inizio di una dichiarazione di namespace — ovvero un attributo xmlns o xmlns:prefix che porta un namespace nell'ambito corrente. Appartiene all'estensione PHP a basso livello e basata su eventi XML Parser (SAX) e non ha relazione con SimpleXML o DOM, che analizzano l'intero documento in un albero anziché tramite eventi in streaming.
Questo handler è utile quando si analizzano documenti XML di grandi dimensioni o in streaming e si ha bisogno di sapere quali namespace sono attivi — ad esempio, per mappare i prefissi agli URI, per verificare che un namespace richiesto sia presente, o per indirizzare gli elementi a processori diversi in base al loro namespace.
Requisito fondamentale: gli handler dei namespace si attivano solo se il parser è consapevole dei namespace. È necessario creare il parser con
xml_parser_create_ns(), non conxml_parser_create(). Un parser semplice ignora silenziosamente gli attributixmlns, quindi questo handler non verrà mai chiamato.
Sintassi
xml_set_start_namespace_decl_handler($parser, $handler): bool| Parametro | Descrizione |
|---|---|
$parser | Un parser XML consapevole dei namespace creato con xml_parser_create_ns(). |
$handler | Il callback da eseguire per ogni evento di inizio namespace. Passare il nome di una funzione (string), una closure, o null per rimuovere un handler precedentemente impostato. |
La funzione restituisce true in caso di successo o false in caso di errore.
La firma del callback
L'handler riceve tre argomenti:
function handler($parser, $prefix, $uri): void$parser— il parser che ha generato l'evento.$prefix— il prefisso del namespace, ad esempio"ns"perxmlns:ns="…". Per un namespace predefinito (xmlns="…") il prefisso è il booleanfalse, non una stringa vuota.$uri— l'URI del namespace a cui è associato il prefisso.
Esempio: lettura delle dichiarazioni di namespace
L'esempio seguente analizza un documento in stile Atom con due namespace e stampa ciascuno di essi non appena entra nell'ambito. Si noti l'uso di xml_parser_create_ns() affinché gli eventi vengano effettivamente generati:
function handleStartNamespace($parser, $prefix, $uri) {
// A default namespace (xmlns="...") arrives as prefix === false.
$name = ($prefix === false) ? "(default)" : $prefix;
echo "Namespace in scope -> $name = $uri\n";
}
$parser = xml_parser_create_ns();
xml_set_start_namespace_decl_handler($parser, "handleStartNamespace");
$xml = '<?xml version="1.0"?>
<root xmlns:ns="http://example.com/ns"
xmlns:meta="http://example.com/meta">
<ns:item>Test</ns:item>
</root>';
// The third argument `true` marks this as the final chunk of data.
xml_parse($parser, $xml, true);
xml_parser_free($parser);Output:
Namespace in scope -> ns = http://example.com/ns
Namespace in scope -> meta = http://example.com/metaIl parser genera un evento per ogni namespace dichiarato, nell'ordine in cui appaiono gli attributi xmlns, prima di segnalare l'elemento che li ha dichiarati.
Errori comuni
- Parser semplice, nessun evento. Se si crea il parser con
xml_parser_create()invece dixml_parser_create_ns(), l'handler non viene mai chiamato e non si vedrà alcun output — una frequente fonte di confusione del tipo "non funziona". - Il prefisso del namespace predefinito è
false. Confrontare sempre con===($prefix === false); un testif (!$prefix)cattura anche il prefisso legittimo"0". - Abbinare con l'handler finale. Il complementare
xml_set_end_namespace_decl_handler()segnala quando un namespace esce dall'ambito, il che è importante quando si traccia l'annidamento. - Liberare il parser. Chiamare
xml_parser_free()al termine per rilasciare la risorsa.
Funzioni correlate
xml_parser_create_ns()— crea il parser consapevole dei namespace richiesto da questo handler.xml_set_end_namespace_decl_handler()— l'handler corrispondente per la fine dell'ambito.xml_set_element_handler()— gestisce i tag di inizio/fine degli elementi.xml_parse()— invia i dati al parser e attiva i callback.
Conclusione
xml_set_start_namespace_decl_handler() consente di reagire ai namespace non appena entrano nell'ambito durante lo streaming XML con il parser SAX. L'unica cosa che crea problemi è il parser: gli eventi dei namespace si attivano solo quando il parser è creato con xml_parser_create_ns(). Ricordare che un namespace predefinito arriva con un prefisso false, abbinare l'handler con xml_set_end_namespace_decl_handler() quando si ha bisogno del tracciamento dell'ambito, e liberare il parser al termine.