W3docs

xml_set_unparsed_entity_decl_handler()

La función xml_set_unparsed_entity_decl_handler() de PHP define un callback para manejar declaraciones de entidades no analizadas en un parser XML SAX.

La función xml_set_unparsed_entity_decl_handler() define un callback personalizado como manejador de declaraciones de entidades no analizadas en un parser XML. Pertenece a la extensión XML Parser (SAX) de PHP y forma parte de la misma familia que xml_set_element_handler() y xml_set_character_data_handler() — no aplica a SimpleXML ni al DOM.

Una entidad no analizada es una entidad cuyo contenido el procesador XML no debe analizar como XML — típicamente una referencia a datos binarios externos como una imagen, PDF o archivo de audio. Se declara con la palabra clave NDATA seguida de un nombre de notación, por ejemplo:

<!ENTITY logo SYSTEM "logo.png" NDATA png>

Cuando el parser encuentra dicha declaración en el DTD del documento, invoca tu manejador para que puedas registrar dónde reside el recurso en lugar de intentar cargarlo como marcado.

Sintaxis

xml_set_unparsed_entity_decl_handler(
    XMLParser $parser,
    callable $handler
): true
ParámetroDescripción
$parserEl parser XML creado con xml_parser_create().
$handlerUn callable, o el nombre en string de una función. Pasa una cadena vacía ("") para eliminar el manejador actual.

Valor de retorno: siempre devuelve true.

Nota PHP 8: desde PHP 8.0 el parser es un objeto XMLParser en lugar de un resource, pero el código que se escribe es idéntico — sigue tratando el valor que devuelve xml_parser_create() como un handle opaco.

La firma del callback

Tu manejador se invoca con seis argumentos, en este orden:

handler(
    XMLParser $parser,
    string $entityName,    // e.g. "logo"
    string $base,          // base URI used to resolve the system id (often empty)
    string $systemId,      // e.g. "logo.png"
    string $publicId,      // public id, if any
    string $notationName   // e.g. "png" — declared with xml_set_notation_decl_handler()
): void

Ejemplo: capturar declaraciones de entidades no analizadas

Crea un parser SAX con xml_parser_create(), registra el manejador y luego alimenta el XML a xml_parse():

<?php
function handleUnparsedEntity($parser, $name, $base, $systemId, $publicId, $notationName) {
    echo "Unparsed entity '$name' -> $systemId (notation: $notationName)\n";
}

$xmlParser = xml_parser_create();
xml_set_unparsed_entity_decl_handler($xmlParser, "handleUnparsedEntity");

$xml = '<?xml version="1.0"?>
<!DOCTYPE catalog [
  <!NOTATION png SYSTEM "image/png">
  <!ENTITY logo SYSTEM "logo.png" NDATA png>
  <!ENTITY manual SYSTEM "manual.pdf" NDATA pdf>
]>
<catalog/>';

xml_parse($xmlParser, $xml, true);
xml_parser_free($xmlParser);

Salida esperada:

Unparsed entity 'logo' -> logo.png (notation: png)
Unparsed entity 'manual' -> manual.pdf (notation: pdf)

El manejador se ejecuta una vez por cada entidad NDATA del DTD, proporcionando la ruta del archivo ($systemId) y la notación. Una aplicación real almacenaría estas referencias — por ejemplo, para descargar los recursos más tarde — en lugar de mostrarlos por pantalla.

Errores comunes

  • El DTD debe contener declaraciones NDATA. Una entidad interna normal (<!ENTITY name "value">) es texto analizado, por lo que este manejador nunca la ve. Solo las entidades marcadas con NDATA notation son "no analizadas".
  • Registra los manejadores antes de llamar a xml_parse(). Como cualquier función xml_set_*_handler(), esta no tiene efecto una vez que el análisis ha comenzado.
  • Libera el parser con xml_parser_free() cuando hayas terminado para liberar recursos.
  • No aplica en SimpleXML. Si estás leyendo XML bien formado y no necesitas reaccionar a las declaraciones de entidades del DTD, el parser SimpleXML suele ser la mejor opción.

Funciones relacionadas

Conclusión

xml_set_unparsed_entity_decl_handler() permite que un parser SAX te notifique sobre entidades NDATA — referencias a datos binarios externos — para que puedas capturar sus rutas y notaciones sin intentar analizarlas como XML. Registra el manejador antes de xml_parse(), espera el callback con seis argumentos y recuerda que la función solo aplica a la extensión procedural XML Parser, no a SimpleXML ni al DOM.

Práctica

Práctica
¿Cuál es la función de xml_set_unparsed_entity_decl_handler en PHP?
¿Cuál es la función de xml_set_unparsed_entity_decl_handler en PHP?
Was this page helpful?