xml_set_start_namespace_decl_handler()
A função xml_set_start_namespace_decl_handler() define uma função personalizada como handler para declarações de início de namespace em PHP
A função xml_set_start_namespace_decl_handler() registra um callback que o parser XML invoca sempre que encontra o início de uma declaração de namespace — ou seja, um atributo xmlns ou xmlns:prefix que coloca um namespace em escopo. Ela pertence à extensão de baixo nível e orientada a eventos XML Parser (SAX) do PHP e não está relacionada ao SimpleXML ou ao DOM, que analisam o documento inteiro em uma árvore em vez de transmitir eventos.
Você utiliza este handler quando faz o parse de XML grande ou em streaming e precisa saber quais namespaces estão ativos — por exemplo, para mapear prefixos a URIs, validar que um namespace obrigatório está presente, ou despachar elementos para diferentes processadores com base no namespace.
Requisito fundamental: os handlers de namespace só disparam se o parser tiver suporte a namespaces. Você deve criar o parser com
xml_parser_create_ns(), não comxml_parser_create(). Um parser simples ignora silenciosamente os atributosxmlns, portanto este handler nunca será chamado.
Sintaxe
xml_set_start_namespace_decl_handler($parser, $handler): bool| Parâmetro | Descrição |
|---|---|
$parser | Um parser XML com suporte a namespaces criado por xml_parser_create_ns(). |
$handler | O callback a ser executado em cada evento de início de namespace. Passe um nome de função (string), uma closure, ou null para remover um handler definido anteriormente. |
A função retorna true em caso de sucesso ou false em caso de falha.
A assinatura do callback
Seu handler recebe três argumentos:
function handler($parser, $prefix, $uri): void$parser— o parser que disparou o evento.$prefix— o prefixo do namespace, ex.:"ns"paraxmlns:ns="…". Para um namespace padrão (xmlns="…"), o prefixo é o booleanfalse, não uma string vazia.$uri— o URI do namespace ao qual o prefixo está vinculado.
Exemplo: lendo declarações de namespace
O exemplo abaixo faz o parse de um documento no estilo Atom com dois namespaces e imprime cada um conforme entra em escopo. Observe o uso de xml_parser_create_ns() para que os eventos realmente disparem:
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);Saída:
Namespace in scope -> ns = http://example.com/ns
Namespace in scope -> meta = http://example.com/metaO parser gera um evento por namespace declarado, na ordem em que os atributos xmlns aparecem, antes de reportar o elemento que os declarou.
Problemas comuns
- Parser simples, sem eventos. Se você criar o parser com
xml_parser_create()em vez dexml_parser_create_ns(), o handler nunca é chamado e você não verá nenhuma saída — uma fonte frequente de confusão do tipo "não está funcionando". - O prefixo do namespace padrão é
false. Sempre compare com===($prefix === false); um testeif (!$prefix)também captura o prefixo legítimo"0". - Combine com o handler de fim. O complemento
xml_set_end_namespace_decl_handler()marca onde um namespace sai do escopo, o que importa quando você rastreia aninhamentos. - Libere o parser. Chame
xml_parser_free()quando terminar para liberar o recurso.
Funções relacionadas
xml_parser_create_ns()— cria o parser com suporte a namespaces exigido por este handler.xml_set_end_namespace_decl_handler()— o handler correspondente para o fim do escopo.xml_set_element_handler()— trata as tags de início e fim de elementos.xml_parse()— alimenta dados ao parser e aciona os callbacks.
Conclusão
xml_set_start_namespace_decl_handler() permite reagir aos namespaces conforme eles entram em escopo durante o streaming de XML com o parser SAX. O único detalhe que costuma confundir as pessoas é o parser: os eventos de namespace só disparam quando o parser é criado com xml_parser_create_ns(). Lembre-se de que um namespace padrão chega com um prefixo false, combine o handler com xml_set_end_namespace_decl_handler() quando precisar rastrear escopos, e libere o parser ao terminar.