2009-08-13 23 views
11

Busco y proceso archivos XML desde otro lugar, y necesito transformarlos con algunos XSLT. No hay problema. Usando PHP5 y la biblioteca DOM , todo es muy fácil. Funcionó bien, hasta ahora. Hoy en día, los caracteres de funky estaban en el archivo XML: comillas "inteligentes" de Word, parece que . De todos modos, DOMDocument-> cargar se quejó de ellos, diciendo que no eran UTF-8, y para especificar la codificación.¿Cómo le digo a DOMDocument-> load() qué codificación quiero que use?

Mira, la codificación no está especificada en estos archivos XML. Si I agrega 'encoding = "iso-8859-1"' al encabezado, funciona bien. El problema es No tengo control sobre estos archivos XML.

Leyendo el archivo en una cadena, la modificación de su cabecera y escribir de nuevo a otra ubicación parece ser mi única opción, pero yo prefiero hacer sin tener que utilizar copias temporales de los archivos XML en todas. ¿Hay alguna forma de que simplemente le diga al analizador que las analice como si fueran iso-8859-1?

Respuesta

9

¿Esto funciona para usted?

$doc = new DOMDocument('1.0', 'iso-8859-1'); 
$doc->load($xmlPath); 

Editar: Dado que parece que esto no funciona, lo que podría hacer en su lugar es similar a su método existente pero sin el archivo temporal. Leer el archivo XML de su fuente simplemente usando operaciones estándar (IO file_get_contents() o algo así), a continuación, realizar cualquier cambio en la codificación que necesita (o iconv()utf8_decode()) y luego usar loadXML()

$myXMLString = file_get_contents($xmlPath); 
$myXMLString = utf8_decode($myXMLString); 
$doc = new DOMDocument('1.0', 'iso-8859-1'); 
$doc->loadXML($myXMLString); 
+1

probado este - no parece afectar el documento cargado - de mi lectura, me Estoy bastante seguro de que la codificación se restablece mediante la llamada a load() – Loki

5

no he encontrado una manera para establecer la codificación predeterminada (todavía) pero quizás el modo de recuperación es factible en este caso.
Cuando libxml encuentra un error de codificación y no se ha establecido explícitamente ninguna codificación, cambia de unicode/utf8 a latin1 y continúa el análisis del documento. Pero en el contexto del analizador, la propiedad wellFormed está configurada en 0/falso. La extensión DOM de PHP considera que el documento es válido si wellFormed es verdadero o el atributo del objeto DOMDocument recover es verdadero.

<?php 
// german Umlaut ä in latin1 = 0xE4 
$xml = '<foo>'.chr(0xE4).'</foo>'; 

$doc = new DOMDocument; 
$b = $doc->loadxml($xml); 
echo 'with doc->recover=false(default) : ', ($b) ? 'success':'failed', "\n"; 

$doc = new DOMDocument; 
$doc->recover = true; 
$b = $doc->loadxml($xml); 
echo 'with doc->recover=true : ', ($b) ? 'success':'failed', "\n"; 

impresiones

Warning: DOMDocument::loadXML(): Input is not proper UTF-8, indicate encoding ! 
Bytes: 0xE4 0x3C 0x2F 0x66 in Entity, line: 1 in test.php on line 6 
with doc->recover=false(default) : failed 

Warning: DOMDocument::loadXML(): Input is not proper UTF-8, indicate encoding ! 
Bytes: 0xE4 0x3C 0x2F 0x66 in Entity, line: 1 in test.php on line 11 
with doc->recover=true : success 

Aún obtiene el mensaje de advertencia (que puede ser suprimida por @ $ doc-> load()) y también se mostrará en el internal libxml errors (sólo una vez cuando el el analizador cambia de utf8 a latin1). El código de error para este error en particular será 9 (XML_ERR_INVALID_CHAR).

<?php 
$xml = sprintf('<foo> 
    <ae>%s</ae> 
    <oe>%s</oe> 
    & 
</foo>', chr(0xE4),chr(0xF6)); 

libxml_use_internal_errors(true); 
$doc = new DOMDocument; 
$doc->recover = true; 
libxml_clear_errors(); 
$b = $doc->loadxml($xml); 
$invalidCharFound = false; 
foreach(libxml_get_errors() as $error) { 
    if (9==$error->code && !$invalidCharFound) { 
     $invalidCharFound = true; 
     echo "found invalid char, possibly harmless\n"; 
    } 
    else { 
     echo "hm, that's probably more severe: ", $error->message, "\n"; 
    } 
} 
2

La forma inmejorable para especificar la codificación es en la declaración XML al inicio del archivo:

<?xml version="1.0" encoding="ISO-8859-1"?> 
+0

Esta es la única respuesta correcta; consulte también http://stackoverflow.com/questions/8218230/php-domdocument-loadhtml-not-encoding-utf-8- correctamente – iquito

Cuestiones relacionadas