W3docs

xml_set_notation_decl_handler()

A função xml_set_notation_decl_handler() define um callback para declarações de notação em um parser XML SAX do PHP.

A função xml_set_notation_decl_handler() registra um callback definido pelo usuário que o parser SAX (Expat) invoca sempre que encontra uma declaração de notação no DTD do documento. Ela pertence à extensão xml do PHP e funciona apenas com um parser criado por xml_parser_create() — não tem efeito sobre SimpleXML ou DOM.

Uma declaração de notação tem esta aparência dentro de um <!DOCTYPE ...>:

<!NOTATION png SYSTEM "image/png">

As notações nomeiam um formato de dados externo (um tipo de imagem, um programa auxiliar, etc.) para que o formato possa ser referenciado posteriormente por uma entidade não analisada. Elas são raras no XML moderno, mas quando um DTD as contém, esse handler permite interceptar, registrar ou validar cada uma durante a análise em vez de descartá-la silenciosamente.

Nota: A extensão xml (Expat) deve estar habilitada em sua compilação do PHP. Declarações de notação aparecem somente dentro de um DTD interno ou externo, portanto um documento sem <!DOCTYPE> nunca aciona este handler.

Sintaxe

xml_set_notation_decl_handler(
    XMLParser $parser,
    callable|false $handler
): bool
  • $parser — o recurso do parser retornado por xml_parser_create() (ou xml_parser_create_ns()).
  • $handler — o callback a ser executado para cada declaração de notação, ou false para remover um handler definido anteriormente.

Retorna true em caso de sucesso e false se $parser não for um parser válido.

A assinatura do callback

Seu handler recebe cinco argumentos nesta ordem fixa:

function handler($parser, $notation_name, $base, $system_id, $public_id)
ParâmetroSignificado
$parserO parser que acionou o handler.
$notation_nameO nome dado à notação, por exemplo, png.
$baseO URI base para resolver os identificadores (geralmente vazio).
$system_idO identificador SYSTEM, ou ""/null se ausente.
$public_idO identificador PUBLIC, ou ""/null se ausente.

Uma notação pode usar SYSTEM (apenas identificador de sistema) ou PUBLIC (identificador público e um identificador de sistema), portanto verifique quais campos estão preenchidos antes de utilizá-los.

Exemplo: lendo declarações de notação

O parser a seguir imprime cada notação encontrada, incluindo as formas SYSTEM e PUBLIC:

function handle_notation_decl($parser, $notation_name, $base, $system_id, $public_id) {
    echo "Notation name: $notation_name\n";
    echo "  System ID:   " . ($system_id ?? '(none)') . "\n";
    echo "  Public ID:   " . ($public_id ?? '(none)') . "\n";
}

$xml_parser = xml_parser_create();
xml_set_notation_decl_handler($xml_parser, "handle_notation_decl");

$xml_data = <<<XML
<?xml version="1.0"?>
<!DOCTYPE root [
  <!NOTATION png SYSTEM "image/png">
  <!NOTATION gif PUBLIC "-//IETF//NOTATION GIF89a//EN" "http://www.w3.org/Graphics/GIF/spec-gif89a.txt">
]>
<root/>
XML;

if (!xml_parse($xml_parser, $xml_data, true)) {
    echo "XML error: " . xml_error_string(xml_get_error_code($xml_parser)) . "\n";
}
xml_parser_free($xml_parser);

Isto imprime:

Notation name: png
  System ID:   image/png
  Public ID:   (none)
Notation name: gif
  System ID:   http://www.w3.org/Graphics/GIF/spec-gif89a.txt
  Public ID:   -//IETF//NOTATION GIF89a//EN

Observe que para a notação SYSTEM apenas o ID do sistema é definido, enquanto a notação PUBLIC preenche ambos os identificadores. O terceiro argumento true para xml_parse() marca os dados como o último bloco, e xml_parser_free() libera o parser quando você terminar.

Problemas comuns

  • Sem DTD, sem callback. O handler é acionado apenas para declarações <!NOTATION>, que residem dentro de <!DOCTYPE>. Um documento simples nunca o aciona.
  • Registre antes de analisar. Defina o handler antes da primeira chamada a xml_parse(); as declarações são reportadas conforme o parser lê o DTD.
  • Use um método como callback. Passe [$object, 'method'] (ou vincule com xml_set_object()) quando o handler estiver em uma classe.
  • Combine com entidades não analisadas. Notações são normalmente referenciadas por entidades NDATA — trate-as com xml_set_unparsed_entity_decl_handler().

Handlers relacionados

xml_set_notation_decl_handler() é um dos vários callbacks SAX que você pode anexar ao mesmo parser:

Conclusão

xml_set_notation_decl_handler() permite interceptar declarações <!NOTATION> durante a análise SAX em vez de ignorá-las. Registre um callback de cinco argumentos antes da análise, inspecione os identificadores de sistema e público que ele recebe, e combine-o com os outros handlers xml_set_* para processar um documento orientado por DTD de ponta a ponta. Para um contexto mais amplo, consulte o capítulo PHP XML Parser.

Prática

Prática
Quantos argumentos um callback de xml_set_notation_decl_handler() recebe?
Quantos argumentos um callback de xml_set_notation_decl_handler() recebe?
Was this page helpful?