Saltar al contenido

php: al usar DomDocument cada vez que intento escribir UTF-8, escribe su notación hexadecimal

El tutorial o código que encontrarás en este post es la solución más rápida y válida que encontramos a tu duda o dilema.

Solución:

OK aquí tienes:

$dom = new DOMDocument('1.0', 'utf-8');
$dom->appendChild($dom->createElement('root'));
$dom->documentElement->appendChild(new DOMText('ירושלים'));
echo $dom->saveXml();

funcionará bien, porque en este caso, el documento que construyó conservará la codificación especificada como segundo argumento:


ירושלים

Sin embargo, una vez que cargue XML en un documento que no especifica una codificación, perderá todo lo que haya declarado en el constructor, lo que significa:

$dom = new DOMDocument('1.0', 'utf-8');
$dom->loadXml(''); // missing prolog
$dom->documentElement->appendChild(new DOMText('ירושלים'));
echo $dom->saveXml();

no tendrá una codificación de utf-8:


ירושלים

Entonces, si carga algo en XML, asegúrese de que sea

$dom = new DOMDocument();
$dom->loadXml('');
$dom->documentElement->appendChild(new DOMText('ירושלים'));
echo $dom->saveXml();

y funcionará como se esperaba.

Como alternativa, también puede especificar la codificación después de cargar el documento.

Si desea generar UTF-8 con DOMDocument, debe especificarlo. Sencillo, ¿no es así? Si ya huele una pregunta con trampa, no está muy lejos, pero a primera vista, es realmente sencillo.

Considere el siguiente ejemplo de código (codificado en UTF-8) que genera entidades hexadecimales:

$dom = new DOMDocument();
$dom->loadXml('ירושלים');
$dom->save('php://output');

Producción:


ירושלים

Como está escrito, si desea generar esto como UTF-8, debe especificarlo y es sencillo:

...
$dom->encoding = 'UTF-8';
$dom->save('php://output');

La salida entonces está en UTF-8. explícitamente:


ירושלים

Hasta aquí la parte sencilla. Si está interesado en los pequeños detalles sucios, puede seguir leyendo; si no, no pregunte “¿por qué?” :).

Acabo de escribir “en UTF-8 explícitamente porque también en el primer ejemplo la salida está codificada en UTF-8, el XML solo contenía entidades hexadecimales, lo cual es perfectamente válido, ¡incluso en UTF-8!

Ya te habrás dado cuenta de que empiezo con la selección de nitidez aquí, pero recuerda: UTF-8 es el codificación predeterminada de XML.

Y si ahora comienza a decir: Oye, espera, si la codificación predeterminada es UTF-8 de todos modos, ¿por qué PHP DOMDocument utilizar las entidades en primer lugar?

Bueno, la verdad es que lo hace no contrariamente al hallazgo de la pregunta. No siempre.

Vea el siguiente ejemplo que usa un comentario XML en lugar de un valor de nodo que contiene las letras Ivrit:

$dom = new DOMDocument();
$dom->loadXml('');
$dom->save('php://output');

Producción:



¿Está todo despejado? Entonces, el pequeño secreto sucio aquí es: ya sea que tenga esas entidades XML allí o no, para el documento no hace una diferencia, es solo una forma diferente de escribir los mismos datos de caracteres XML. Y ya se siente invitado: intentemos CDATA en su lugar para el primer ejemplo:

$dom = new DOMDocument();
$dom->loadXML("");
$dom->save('php://output');

Producción:



Como esto demuestra como con el ejemplo de comentario XML anterior, no se utilizan entidades XML aquí. Bueno, de todos modos no serían válidos, como en el ejemplo de comentario XML.

Para la descripción general, creemos un ejemplo que contenga todos estos:

$dom = new DOMDocument();
$dom->loadXML("ירושלים ");
$dom->save('php://output');

Producción:



ירושלים 

Lecciones aprendidas:

  • Siempre se usa UTF-8. Solo algunas entidades se utilizan en PCDATA a menos que se especifique la codificación UTF-8. Si se especifica una codificación diferente a UTF-8, se aplican reglas diferentes.
  • No puede especificar si desea utilizar entidades o no para la salida por cargando un documento XML codificado en UTF-8 string en PHP DOMDocument per se. Ni siquiera con banderas libxml ni proporcionando una lista de materiales. [1]
  • Puede especificar que no desea utilizar entidades configurando la codificación de los documentos en UTF-8.
  • Si puede, puede manipular la entrada string tener una declaración XML que especifique la codificación de los documentos como se describe en la respuesta de gordon.

Propina: Si tu string tiene una declaración XML que no coincide con la codificación de cadenas o desea cambiar cualquiera de los dos antes de cargando el string en DOMDocument necesita cambiar la declaración XML y / o volver a codificar la string. Esto se ha cubierto en una respuesta a la pregunta PHP XMLReader, obtenga la versión y la codificación mostrando cómo XMLRecoder trabajos de clase.

Y eso es todo, con suerte.


[1] Probablemente si carga desde una solicitud HTTP y proporciona contexto de transmisión y marca la codificación de caracteres a través de metadatos, pero esto debería probarse primero, no lo sé. Que la lista de materiales no funcione es una señal de que todas estas cosas no funcionan.

Aparentemente, pasar el documentElement como $ node para saveXML funciona en torno a esto, aunque no puedo decir que entiendo por qué.

p.ej

$dom->saveXML($dom->documentElement);

en vez de:

$dom->saveXML();

Fuente: http://www.php.net/manual/en/domdocument.savexml.php#88525

Acuérdate de que tienes la capacidad de agregar una reseña si encontraste tu traba justo a tiempo.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *