W3docs

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 con xml_parser_create(). Un parser semplice ignora silenziosamente gli attributi xmlns, quindi questo handler non verrà mai chiamato.

Sintassi

xml_set_start_namespace_decl_handler($parser, $handler): bool
ParametroDescrizione
$parserUn parser XML consapevole dei namespace creato con xml_parser_create_ns().
$handlerIl 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" per xmlns:ns="…". Per un namespace predefinito (xmlns="…") il prefisso è il boolean false, 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/meta

Il 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 di xml_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 test if (!$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

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.

Esercizio

Pratica
Cosa fa la funzione xml_set_start_namespace_decl_handler() in PHP?
Cosa fa la funzione xml_set_start_namespace_decl_handler() in PHP?
Was this page helpful?