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 porxml_parser_create()(oxml_parser_create_ns()).$handler— el callback que se ejecutará para cada declaración de notación, ofalsepara 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ámetro | Significado |
|---|---|
$parser | El analizador que activó el manejador. |
$notation_name | El nombre asignado a la notación, p. ej. png. |
$base | El URI base para resolver los identificadores (generalmente vacío). |
$system_id | El identificador SYSTEM, o ""/null si está ausente. |
$public_id | El 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//ENObserva 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 conxml_set_object()) cuando el manejador está en una clase. - Combinar con entidades sin analizar. Las notaciones normalmente son referenciadas por entidades
NDATA— manéjalas conxml_set_unparsed_entity_decl_handler().
Manejadores relacionados
xml_set_notation_decl_handler() es uno de varios callbacks SAX que puedes asociar al mismo analizador:
xml_set_element_handler()— etiquetas de apertura y cierre.xml_set_character_data_handler()— contenido de texto.xml_set_unparsed_entity_decl_handler()— entidades sin analizar (NDATA).xml_set_default_handler()— todo lo que no tiene un manejador específico.
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.