W3docs

xml_set_notation_decl_handler()

La función xml_set_notation_decl_handler() de PHP registra un callback para manejar declaraciones de notación en el DTD durante el análisis SAX con Expat.

La función xml_set_notation_decl_handler() registra un callback definido por el usuario que el analizador SAX (Expat) invoca cada vez que encuentra una declaración de notación en el DTD del documento. Pertenece a la extensión xml de PHP y solo funciona con un analizador creado por xml_parser_create() — no tiene efecto sobre SimpleXML ni sobre DOM.

Una declaración de notación tiene este aspecto dentro de un <!DOCTYPE ...>:

<!NOTATION png SYSTEM "image/png">

Las notaciones nombran un formato de datos externo (un tipo de imagen, un programa auxiliar, etc.) para que el formato pueda ser referenciado posteriormente por una entidad sin analizar. Son poco frecuentes en el XML moderno, pero cuando un DTD las contiene, este manejador permite interceptar, registrar o validar cada una durante el análisis en lugar de descartarla silenciosamente.

Nota: La extensión xml (Expat) debe estar habilitada en tu compilación de PHP. Las declaraciones de notación solo aparecen dentro de un DTD interno o externo, por lo que un documento sin <!DOCTYPE> nunca activa este manejador.

Sintaxis

xml_set_notation_decl_handler(
    XMLParser $parser,
    callable|false $handler
): bool
  • $parser — el recurso del analizador devuelto por xml_parser_create() (o xml_parser_create_ns()).
  • $handler — el callback que se ejecutará para cada declaración de notación, o false para eliminar un manejador previamente establecido.

Devuelve true en caso de éxito y false si $parser no es un analizador válido.

La firma del callback

El manejador recibe cinco argumentos en este orden fijo:

function handler($parser, $notation_name, $base, $system_id, $public_id)
ParámetroSignificado
$parserEl analizador que activó el manejador.
$notation_nameEl nombre asignado a la notación, p. ej. png.
$baseEl URI base para resolver los identificadores (generalmente vacío).
$system_idEl identificador SYSTEM, o ""/null si está ausente.
$public_idEl identificador PUBLIC, o ""/null si está ausente.

Una notación puede usar SYSTEM (solo identificador de sistema) o PUBLIC (identificador público y un identificador de sistema), así que verifica qué campos están rellenos antes de usarlos.

Ejemplo: lectura de declaraciones de notación

El siguiente analizador imprime cada notación que encuentra, incluyendo las formas SYSTEM y 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);

Esto 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

Observa que para la notación SYSTEM solo se establece el ID de sistema, mientras que la notación PUBLIC rellena ambos identificadores. El tercer argumento true en xml_parse() marca los datos como el fragmento final, y xml_parser_free() libera el analizador cuando has terminado.

Errores comunes

  • Sin DTD, sin callback. El manejador solo se activa para declaraciones <!NOTATION>, que viven dentro de <!DOCTYPE>. Un documento sin DTD nunca lo activa.
  • Registrar antes de analizar. Establece el manejador antes de la primera llamada a xml_parse(); las declaraciones se notifican a medida que el analizador lee el DTD.
  • Usar un método como callback. Pasa [$object, 'method'] (o vincula con xml_set_object()) cuando el manejador está en una clase.
  • Combinar con entidades sin analizar. Las notaciones normalmente son referenciadas por entidades NDATA — manéjalas con xml_set_unparsed_entity_decl_handler().

Manejadores relacionados

xml_set_notation_decl_handler() es uno de varios callbacks SAX que puedes asociar al mismo analizador:

Conclusión

xml_set_notation_decl_handler() permite interceptar declaraciones <!NOTATION> durante el análisis SAX en lugar de ignorarlas. Registra un callback de cinco argumentos antes de analizar, inspecciona los identificadores de sistema y público que recibe, y combínalo con los demás manejadores xml_set_* para procesar un documento basado en DTD de principio a fin. Para mayor contexto, consulta el capítulo PHP XML Parser.

Práctica

Práctica
¿Cuántos argumentos recibe un callback de xml_set_notation_decl_handler()?
¿Cuántos argumentos recibe un callback de xml_set_notation_decl_handler()?
Was this page helpful?