Advertencias 'xmlParseEntityRef: sin nombre' al cargar xml en un archivo php


89

Estoy leyendo un xml en php usando simplexml_load_file. Sin embargo, al intentar cargar el xml, muestra una lista de advertencias

Warning: simplexml_load_file() [function.simplexml-load-file]: <project orderno="6" campaign_name="International Relief & Development" project in /home/bluecard1/public_html/test.php on line 3    
Warning: simplexml_load_file() [function.simplexml-load-file]: ^ in /home/bluecard1/public_html/test.php on line 3    
Warning: simplexml_load_file() [function.simplexml-load-file]: http://..../index.php/site/projects/:15: parser error : xmlParseEntityRef: no name in /home/bluecard1/public_html/test.php on line 3

Warning: simplexml_load_file() [function.simplexml-load-file]: ional Relief & Development" project_id="313" client_name="International Relief & in /home/bluecard1/public_html/test.php on line 3    
Warning: simplexml_load_file() [function.simplexml-load-file]: ^ in /home/bluecard1/public_html/test.php on line 3    
Warning: simplexml_load_file() [function.simplexml-load-file]: http://..../index.php/site/projects/:15: parser error : xmlParseEntityRef: no name in /home/bluecard1/public_html/test.php on line 3

¿Cómo rectifico para eliminar estas advertencias?

(XML se genera a partir de la url http://..../index.php/site/projectsy se carga en una variable en test.php. No tengo privilegios de escritura en index.php)


El XML no es válido. Es posible que no pueda cargarlo en absoluto. Los errores se pueden eliminar agregando @delante simplexml_load_fileo agregando una bandera, consulte la página del manual de simplexml_load_filepara obtener más información y elimine su pregunta, es un duplicado.
Hakre

Puedo ver que mi respuesta está recibiendo mucha atención, si esa es realmente la solución: ¿puede marcarla como "respuesta correcta"? Gracias.
ricricucit

Respuestas:


143

Lo más probable es que el XML no sea válido.

El problema podría ser el "&"

$text=preg_replace('/&(?!#?[a-z0-9]+;)/', '&amp;', $text);

eliminará el "&" y lo reemplazará con su versión de código HTML ... pruébelo.


2
Gracias. ¡Salvaste mi día!
Saim

2
La mejor práctica al trabajar con XML es asegurarse de que no haya caracteres en conflicto y debe reemplazarlos antes del análisis
Mr Megamind

2
gracias, el punto principal de esta pregunta es porque xml no es válido
yussan

Solo una pequeña adición, si desea reemplazar todos los símbolos de unión, agregue 'g' a su expresión regular. La solución actualizada se vería así: $text=preg_replace('/&(?!#?[a-z0-9]+;)/g', '&amp;', $text);
flaming.codes

81

Encontré esto aquí ...

Problema: un analizador XML devuelve el error "xmlParseEntityRef: noname"

Causa: Hay un '&' (carácter comercial) en algún lugar del texto XML, por ejemplo. algo de texto y algo más de texto

Solución:

  • Solución 1: Quite el ampersand.
  • Solución 2: codifique el ampersand (es decir, reemplace el &carácter por &amp;). Recuerde decodificar al leer el texto XML.
  • Solución 3: Use secciones CDATA (el analizador ignorará el texto dentro de una sección CDATA). <! [CDATA [algo de texto y algo más de texto]]>

Nota: '&' '<' '>' darán problemas si no se manejan correctamente.


9
Esto me salvó hoy.
Bwire

¿Sabemos por qué es esto? Además, ¿un navegador seguirá recogiendo una sección CDATA que muestre algunos de estos datos? Tengo algunas etiquetas HTML dentro de mis etiquetas XML y necesito que se muestren al usuario final para una herramienta de edición.
sulimmesh

11

Intente limpiar el HTML primero usando esta función:

$html = htmlspecialchars($html);

Los caracteres especiales generalmente se representan de manera diferente en HTML y pueden resultar confusos para el compilador. Como se &convierte &amp;.


¿Alguien puede explicar por qué se vota en contra? htmlspecialchars()es la función precisa para convertir &, ", <, >caracteres en los datos del elemento.
JacobRossDev

7
Esta respuesta tiene una votación negativa porque no funciona bien en este caso. El uso de esa función romperá totalmente su XML al convertir "<" en "& lt;". No conozco ninguna forma en que pueda usar htmlspecialchars()y no romper XML. Probé algunas banderas y mi XML todavía se rompió.
Alex Finnarn

1
Debe usar htmlspecialcharsen el contenido de una etiqueta xml, no en todo el XML
gbalduzzi

7

Yo uso una versión combinada:

strip_tags(preg_replace("/&(?!#?[a-z0-9]+;)/", "&amp;",$textorhtml))

1
Este está funcionando perfectamente. Le falta el corchete final derecho
myh34d

7

PROBLEMA

  • La función PHP simplexml_load_filearroja un error de análisis parser error : xmlParseEntityRefal intentar cargar el archivo XML desde una URL.

PORQUE

  • El XML devuelto por la URL no es un XML válido. Contiene &valor en lugar de &amp;. Es muy posible que haya otros errores que no son obvios en este momento.

COSAS FUERA DE NUESTRO CONTROL

  • Idealmente, deberíamos asegurarnos de que se introduzca un XML válido en PHP simplexml_load_file función , pero parece que no tenemos ningún control sobre cómo se crea el XML.
  • Tampoco es posible forzar el simplexml_load_fileprocesamiento de un archivo XML no válido. No nos deja muchas opciones, aparte de arreglar el archivo XML en sí.

SOLUCIÓN POSIBLE

Convierta XML no válido en XML válido. Se puede hacer usando PHP tidy extension. Se pueden encontrar más instrucciones en http://php.net/manual/en/book.tidy.php

Una vez que esté seguro de que la extensión existe o está instalada, haga lo siguiente.

/**
 * As per the question asked, the URL is loaded into a variable first, 
 * which we can assume to be $xml
 */
$xml = <<<XML
<?xml version="1.0" encoding="UTF-8"?>
<project orderno="6" campaign_name="International Relief & Development for under developed nations">
    <invalid-data>Some other data containing & in it</invalid-data>
    <unclosed-tag>
</project>
XML;

/**
 * Whenever we use tidy it is best to pass some configuration options 
 * similar to $tidyConfig. In this particular case we are making sure that
 * tidy understands that our input and output is XML.
 */
$tidyConfig = array (
    'indent' => true,
    'input-xml' => true, 
    'output-xml' => true,
    'wrap' => 200
);

/**
 * Now we can use tidy to parse the string and then repair it.
 */
$tidy = new tidy;
$tidy->parseString($xml, $tidyConfig, 'utf8');
$tidy->cleanRepair();

/**
 * If we try to output the repaired XML string by echoing $tidy it should look like. 

 <?xml version="1.0" encoding="utf-8"?>
 <project orderno="6" campaign_name="International Relief &amp; Development for under developed nations">
      <invalid-data>Some other data containing &amp; in it</invalid-data>
      <unclosed-tag></unclosed-tag>
 </project> 

 * As you can see that & is now fixed in campaign_name attribute 
 * and also with-in invalid-data element. You can also see that the   
 * <unclosed-tag> which didn't had a close tag, has been fixed too.
 */
echo $tidy;

/**
 * Now when we try to use simplexml_load_string to load the clean XML. When we
 * try to print_r it should look something like below.

 SimpleXMLElement Object
(
    [@attributes] => Array
        (
            [orderno] => 6
            [campaign_name] => International Relief & Development for under developed nations
        )

    [invalid-data] => Some other data containing & in it
    [unclosed-tag] => SimpleXMLElement Object
        (
        )

)

 */
 $simpleXmlElement = simplexml_load_string($tidy);
 print_r($simpleXmlElement);

PRECAUCIÓN

El desarrollador debe intentar comparar el XML no válido con un XML válido (generado por tidy), para ver que no hay efectos secundarios adversos después de usar tidy. Tidy hace un excelente trabajo haciéndolo correctamente, pero nunca está de más verlo visualmente y estar 100% seguro. En nuestro caso debería ser tan sencillo como comparar $ xml con $ tidy.


6

El XML no es válido.

<![CDATA[ 
{INVALID XML}
]]> 

CDATA debe estar envuelto alrededor de todos los caracteres XML especiales, según W3C



1

Esto resuelve mi problema:

$description = strip_tags($value['Description']);
$description=preg_replace('/&(?!#?[a-z0-9]+;)/', '&amp;', $description);
$description= preg_replace("/(^[\r\n]*|[\r\n]+)[\s\t]*[\r\n]+/", "\n", $description);
$description=str_replace(' & ', ' &amp; ', html_entity_decode((htmlspecialchars_decode($description))));

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.