2010-08-26 11 views

Respuesta

14

Ok, aquí va:

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

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

<?xml version="1.0" encoding="utf-8"?> 
<root>ירושלים</root> 

Sin embargo, una vez carga 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('<root/>'); // missing prolog 
$dom->documentElement->appendChild(new DOMText('ירושלים')); 
echo $dom->saveXml(); 

no tendrán una codificación UTF-8:

<?xml version="1.0"?> 
<root>&#x5D9;&#x5E8;&#x5D5;&#x5E9;&#x5DC;&#x5D9;&#x5DD;</root> 

Así que si loadXML algo, asegúrese de que es

$dom = new DOMDocument(); 
$dom->loadXml('<?xml version="1.0" encoding="utf-8"?><root/>'); 
$dom->documentElement->appendChild(new DOMText('ירושלים')); 
echo $dom->saveXml(); 

y funcionará como se espera.

Como alternativa, también puede specify the encoding después de cargar el documento.

3

Al parecer, al pasar el documento Elemento como $ node para guardarXML funciona alrededor de esto, aunque no puedo decir que entiendo por qué.

p. Ej.

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

en lugar de:

$dom->saveXML(); 

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

+0

La diferencia probable es que el objeto '$ dom' no se inicializó con un juego de caracteres para el documento en el constructor, pero el elemento del documento tiene algún sentido de codificación en su contexto. –

0

Cuando creé el DomDocument para escribir, he añadido los siguientes parámetros:

dom = new DOMDocument('1.0','utf-8'); 

estos parámetros causaron la UTF -8 cadena para escribir como es.

0
$doc = new DOMDocument(); 
$doc->loadHTML('<?xml encoding="UTF-8">' . $html); 

// dirty fix 
foreach ($doc->childNodes as $item) 
    if ($item->nodeType == XML_PI_NODE) 
    $doc->removeChild($item); // remove hack 
$doc->encoding = 'UTF-8'; // insert proper 
5

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

Considere lo siguiente (codificación UTF-8) de código ejemplo que da salida a entidades hexadecimales:

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

Salida:

<?xml version="1.0"?> 
<root>&#x5D9;&#x5E8;&#x5D5;&#x5E9;&#x5DC;&#x5D9;&#x5DD;</root> 

Como está escrito, si desea dar salida a esto como UTF-8 , es necesario especificar que, y es sencillo:

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

continuación, la salida está en UTF-8 explícitamente:

<?xml version="1.0" encoding="UTF-8"?> 
<root>ירושלים</root> 

Esto en cuanto a la parte recta hacia adelante. Si le interesan los pequeños y sucios detalles, puede leerlos, si no, no pregunte "¿por qué?" :).

acabo de escribieron "en UTF-8 explícitamente" porque también en el primer ejemplo, la salida es codificación UTF-8, el XML solo contenían entidades hexadecimales que es perfectamente válida - incluso en UTF-8!

Ya ha notado que empiezo con "nit-picking" aquí, pero recuerde: UTF-8 is the default encoding of XML.

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

Bueno, la verdad es que no es, contrario a lo que se encuentra en la pregunta. No siempre.

Véase el siguiente ejemplo que utiliza un comentario-XML en lugar de un valor de nodo que contiene las letras: Ivrit

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

Salida:

<?xml version="1.0"?> 
<root><!-- ירושלים --></root> 

bien, todo claro? Entonces, el pequeño y sucio secreto aquí es: si tienes 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: permite tratar CDATA lugar para el primer ejemplo:

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

Salida:

<?xml version="1.0"?> 
<root><![CDATA[ירושלים]]></root> 

Como esto demuestra que con el ejemplo XML-comentario anterior, no existen entidades XML utilizados aquí . Bueno, de todos modos no serían válidos, como con el ejemplo de comentario XML.

Para la visión general permite crear un ejemplo que contiene todas estas cosas:

$dom = new DOMDocument(); 
$dom->loadXML("<!-- ירושלים --><root>&#x5D9;רושלים <![CDATA[ירושלים]]></root>"); 
$dom->save('php://output'); 

Salida:

<?xml version="1.0"?> 
<!-- ירושלים --> 
<root>&#x5D9;&#x5E8;&#x5D5;&#x5E9;&#x5DC;&#x5D9;&#x5DD; <![CDATA[ירושלים]]></root> 

Lecciones aprendidas:

  • UTF-8 se utiliza siempre. Solo algunas entidades se usan en PCDATA a menos que se especifique la codificación UTF-8. If a different to UTF-8 encoding is specified, different rules apply.
  • No se puede especificar si desea utilizar o no entidades para la salida por carga un documento XML como UTF-8 cadena codificada en los PHP DOMDocument per se. Ni siquiera con libxml flags ni proporcionando una lista de materiales. [1]
  • Puede especificar que no desea utilizar entidades estableciendo la codificación de documentos en UTF-8.
  • Si puede, puede manipular la cadena de entrada que tiene una Declaración XML que especifica los documentos que codifican as outlined in gordon's answer.

Consejo: Si la cadena tiene una Declaración de XML que no coincide con la codificación de cadenas o si desea cambiar cualquiera de los dos antes la carga de la cadena en DOMDocument que tenga que cambiar el XML-Declaration y/o recodificar la cadena. Esto se ha cubierto in an answer a la pregunta PHP XMLReader, get the version and encoding mostrando cómo funciona el XMLRecoder class.

Y eso es todo, con suerte.


[1] Probablemente si se carga de una petición HTTP y le proporcionará contexto de secuencia y la bandera de la codificación de caracteres a través de meta-datos - pero esto debe hacerse la prueba en primer lugar, no sé. Que el BOM no funcione es una señal de que todas estas cosas no funcionan.

0

Para la respuesta punto es:

Cuando su función se inicia, justo después de obtener el contenido, haga lo siguiente:

$content = mb_convert_encoding($content, 'HTML-ENTITIES', 'UTF-8'); 

y luego iniciar el nuevo documento etc. Compruebe esto como ejemplo:

if (empty($content)) { 
     return false; 
    } 
    $doc = new DOMDocument('1.0', 'utf-8'); 
    libxml_use_internal_errors(true); 
    $doc->LoadHTML($content, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD); 

Luego haga lo que tenga la intención de hacer con su código.

Cuestiones relacionadas