W3docs

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 com xml_parser_create(). Um parser simples ignora silenciosamente os atributos xmlns, portanto este handler nunca será chamado.

Sintaxe

xml_set_start_namespace_decl_handler($parser, $handler): bool
ParâmetroDescrição
$parserUm parser XML com suporte a namespaces criado por xml_parser_create_ns().
$handlerO 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" para xmlns:ns="…". Para um namespace padrão (xmlns="…"), o prefixo é o boolean false, 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/meta

O 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 de xml_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 teste if (!$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

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.

Prática

Prática
O que a função xml_set_start_namespace_decl_handler() faz em PHP?
O que a função xml_set_start_namespace_decl_handler() faz em PHP?
Was this page helpful?