xml_set_start_namespace_decl_handler()
La función xml_set_start_namespace_decl_handler() establece una función definida por el usuario como manejador para el inicio de declaraciones de espacio de nombres en PHP
La función xml_set_start_namespace_decl_handler() registra un callback que el analizador XML invoca cada vez que encuentra el inicio de una declaración de espacio de nombres — es decir, un atributo xmlns o xmlns:prefix que introduce un espacio de nombres en el ámbito. Pertenece a la extensión de bajo nivel y orientada a eventos XML Parser (SAX) de PHP y no tiene relación con SimpleXML ni con DOM, que analizan todo el documento en un árbol en lugar de transmitir eventos.
Recurres a este manejador cuando analizas XML grande o en streaming y necesitas saber qué espacios de nombres están activos — por ejemplo, para mapear prefijos a URIs, validar que un espacio de nombres requerido está presente o despachar elementos a diferentes procesadores según su espacio de nombres.
Requisito clave: los manejadores de espacios de nombres solo se disparan si el analizador es consciente de ellos. Debes crear el analizador con
xml_parser_create_ns(), no conxml_parser_create(). Un analizador simple ignora silenciosamente los atributosxmlns, por lo que este manejador nunca será llamado.
Sintaxis
xml_set_start_namespace_decl_handler($parser, $handler): bool| Parámetro | Descripción |
|---|---|
$parser | Un analizador XML consciente de espacios de nombres creado con xml_parser_create_ns(). |
$handler | El callback que se ejecuta en cada evento de inicio de espacio de nombres. Se puede pasar un nombre de función (string), una closure o null para eliminar un manejador previamente establecido. |
La función devuelve true en caso de éxito o false en caso de fallo.
La firma del callback
Tu manejador recibe tres argumentos:
function handler($parser, $prefix, $uri): void$parser— el analizador que disparó el evento.$prefix— el prefijo del espacio de nombres, p. ej."ns"paraxmlns:ns="…". Para un espacio de nombres predeterminado (xmlns="…") el prefijo es el booleanfalse, no una cadena vacía.$uri— el URI del espacio de nombres al que está vinculado el prefijo.
Ejemplo: leer declaraciones de espacio de nombres
El siguiente ejemplo analiza un documento estilo Atom con dos espacios de nombres e imprime cada uno a medida que entra en el ámbito. Observa el uso de xml_parser_create_ns() para que los eventos se disparen realmente:
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);Salida:
Namespace in scope -> ns = http://example.com/ns
Namespace in scope -> meta = http://example.com/metaEl analizador genera un evento por cada espacio de nombres declarado, en el orden en que aparecen los atributos xmlns, antes de reportar el elemento que los declaró.
Errores comunes
- Analizador simple, sin eventos. Si creas el analizador con
xml_parser_create()en lugar dexml_parser_create_ns(), el manejador nunca se llama y no verás ninguna salida — una fuente frecuente de confusión del tipo "no funciona". - El prefijo del espacio de nombres predeterminado es
false. Siempre compara con===($prefix === false); un testif (!$prefix)también captura el prefijo legítimo"0". - Combínalo con el manejador de fin. El complementario
xml_set_end_namespace_decl_handler()marca cuándo un espacio de nombres sale del ámbito, lo cual importa cuando rastreas el anidamiento. - Libera el analizador. Llama a
xml_parser_free()cuando hayas terminado para liberar el recurso.
Funciones relacionadas
xml_parser_create_ns()— crea el analizador consciente de espacios de nombres que requiere este manejador.xml_set_end_namespace_decl_handler()— el manejador de fin de ámbito complementario.xml_set_element_handler()— maneja las etiquetas de inicio y fin de elementos.xml_parse()— alimenta datos al analizador y dispara los callbacks.
Conclusión
xml_set_start_namespace_decl_handler() te permite reaccionar a los espacios de nombres a medida que entran en el ámbito mientras transmites XML con el analizador SAX. Lo que más confunde a la gente es el analizador: los eventos de espacio de nombres solo se disparan cuando el analizador se crea con xml_parser_create_ns(). Recuerda que un espacio de nombres predeterminado llega con un prefijo false, combina el manejador con xml_set_end_namespace_decl_handler() cuando necesites rastrear el ámbito y libera el analizador cuando hayas terminado.