lectura - simplexmlelement php ejemplo
Error del analizador XML: entidad no definida (5)
He buscado stackoverflow en este problema y encontré algunos temas, pero siento que realmente no hay una respuesta sólida para mí en esto.
Tengo un formulario que los usuarios envían y el valor del campo se almacena en un archivo XML. El XML está configurado para codificarse con UTF-8.
De vez en cuando, un usuario copiará / pegará texto de algún lugar y ahí es cuando obtengo el "error de entidad no definida".
Me doy cuenta de que XML solo admite algunas entidades seleccionadas y no se reconoce nada más allá de eso, de ahí el error del analizador.
De lo que deduzco, hay algunas opciones que he visto:
- Puedo encontrar y reemplazar todos los
y cambiarlos con 
o un espacio real. - Puedo colocar el código en cuestión dentro de una sección CDATA.
- Puedo incluir estas entidades dentro del archivo XML.
Lo que estoy haciendo con el archivo XML es que el usuario puede ingresar contenido en un formulario, se almacena en un archivo XML y ese contenido luego se muestra como XHTML en una página web (analizado con SimpleXML).
De las tres opciones, o cualquier otra opción (s) que no conozco, ¿cuál es realmente la mejor manera de tratar con estas entidades?
Gracias Ryan
ACTUALIZAR
Quiero agradecer a todos por la gran retroalimentación. Realmente determiné qué causó los errores de mi entidad. ¡Todas las sugerencias me hicieron profundizar en ello!
Algunos cuadros de texto estaban en cuadros de texto antiguos, pero mis áreas de texto se mejoraron con TinyMCE. Resulta, mientras se analiza más de cerca, que las advertencias de PHP siempre hacen referencia a los datos de las áreas de texto mejoradas de TinyMCE. Más tarde noté en una PC que se eliminaron todos los caracteres (porque no podía leerlos), pero en un MAC se podían ver casillas cuadradas que hacían referencia al número de Unicode de ese carácter. La razón por la que apareció en cuadrados en un MAC en primer lugar, es porque usé utf8_encode para codificar datos que no estaban en UTF para evitar otros errores de análisis (que de alguna manera también están relacionados con TinyMCE).
La solución a todo esto fue bastante simple:
entity_encoding : "utf-8"
esta línea entity_encoding : "utf-8"
en mi tinyMCE.init. Ahora, todos los personajes se muestran como se supone que deben hacer.
Supongo que lo único que no entiendo es por qué los caracteres siguen apareciendo cuando se colocan en cuadros de texto, porque nada los convierte a UTF, pero con TinyMCE fue un problema.
1
. Puedo encontrar y reemplazar todos los [
?] y cambiarlos con [ 
?] o un espacio real.
Este es un método robusto, pero requiere que tengas una tabla de todas las entidades HTML (asumo que la entrada pegada proviene de HTML) y que analices el texto pegado para referencias de entidades.
2
. Puedo colocar el código en cuestión dentro de una sección CDATA.
En otras palabras, deshabilitar el análisis de toda la sección? Entonces tendrías que analizarlo de otra manera. Podría funcionar.
3
. Puedo incluir estas entidades dentro del archivo XML.
¿Quieres decir incluir las definiciones de la entidad? Creo que esta es una forma fácil y robusta, si no te importa hacer el archivo XML un poco más grande. Podría tener un archivo "incluido" (busque uno en la web) que sea una entidad externa, a la que haga referencia desde la parte superior de su archivo XML principal.
Un inconveniente es que el analizador XML que utiliza tiene que ser uno que procesa entidades externas (que no todos los analizadores tienen que hacer). Y debe resolver correctamente la URL (posiblemente relativa) de la entidad externa a algo accesible. Esto no es tan malo, pero puede aumentar las restricciones en sus herramientas de procesamiento.
4
. Podrías prohibir el no XML en el contenido pegado. Entre otras cosas, esto no permitiría referencias de entidades que no estén predefinidas en XML (las 5 que mencionó Tomalak) o definidas en el contenido en sí. Sin embargo, esto puede violar los requisitos de la aplicación, si los usuarios necesitan poder pegar HTML allí.
5
. Puede analizar el contenido pegado como HTML en un árbol DOM configurando someDiv.innerHTML = thePastedContent; En otras palabras, cree un div en algún lugar (probablemente display = none, excepto para la depuración). Supongamos que tiene una variable javascript myDiv
que contiene este elemento div, y otra variable myField
que contiene el elemento que es su campo de entrada de texto. Entonces en javascript lo haces
myDiv.innerHTML = myField.value;
que toma el texto sin analizar de myField, lo analiza en un árbol DOM de HTML y lo pega en myDiv como contenido HTML.
Luego, usaría algún método basado en navegador para serializar (= "des-parsing") el árbol DOM de nuevo a XML. Vea por ejemplo esta pregunta . Luego envías el resultado al servidor como XML.
Si desea realizar esta corrección en el navegador o en el servidor (como sugirió @Hannes), dependerá del tamaño de los datos, de la rapidez de la respuesta, del tamaño de su servidor y de si le interesa el envío de piratas informáticos. XML no bien formado a propósito.
Esta pregunta es un problema general para cualquier lenguaje que analice XML o JSON (así que, básicamente, todos los idiomas).
Las respuestas anteriores son para PHP, pero una solución Perl sería tan fácil como ...
my $excluderegex =
''^/n/x20-/x20'' . # Don''t Encode Spaces
''/x30-/x39'' . # Don''t Encode Numbers
''/x41-/x5a'' . # Don''t Encode Capitalized Letters
''/x61-/x7a'' ; # Don''t Encode Lowercase Letters
# in case anything is already encoded
$value = HTML::Entities::decode_entities($value);
# encode properly to numeric
$value = HTML::Entities::encode_numeric($value, $excluderegex);
Estoy de acuerdo en que es puramente un problema de codificación. En PHP, así es como resolví este problema:
Antes de pasar el fragmento html al constructor
SimpleXMLElement
lo descodifiqué usandohtml_entity_decode
.Luego codificado aún más utilizando
utf8_encode()
.
$headerDoc = ''<temp>'' . utf8_encode(html_entity_decode($headerFragment)) . ''</temp>'';
$xmlHeader = new SimpleXMLElement($headerDoc);
Ahora el código anterior no arroja ningún error de entidad indefinida .
Podría analizar el texto en HTML y hacer que vuelva a escaparse solo con las entidades numéricas respectivas (como:
→  
). En cualquier caso, simplemente usar una entrada de usuario no saneada es una mala idea.
Todas las entidades numéricas están permitidas en XML, solo las denominadas conocidas de HTML no funcionan (con la excepción de &
"
<
>
'
).
Sin embargo, la mayoría de las veces, solo puede escribir el carácter real ( ö
→ ö
) en el archivo XML, por lo que no es necesario utilizar una referencia de entidad. Si está utilizando una API DOM para manipular su XML (¡y debería!) Esta es su apuesta más segura.
Finalmente (esta es la solución perezosa para el desarrollador) puede crear un archivo XML roto (es decir, no está bien formado, con errores de entidad) y simplemente pasarlo por ordenado para las reparaciones necesarias. Esto puede funcionar o puede fallar dependiendo de cuán roto esté todo. Sin embargo, en mi experiencia, tidy es bastante inteligente y te permite salirte con la tuya.
Si quieres convertir todos los caracteres, esto puede ayudarte (lo escribí hace un tiempo):
http://www.lautr.com/convert-all-applicable-characters-to-numeric-entities-for-use-in-xml
function _convertAlphaEntitysToNumericEntitys($entity) {
return ''&#''.ord(html_entity_decode($entity[0])).'';'';
}
$content = preg_replace_callback(
''/&([/w/d]+);/i'',
''_convertAlphaEntitysToNumericEntitys'',
$content);
function _convertAsciOver127toNumericEntitys($entity) {
if(($asciCode = ord($entity[0])) > 127)
return ''&#''.$asciCode.'';'';
else
return $entity[0];
}
$content = preg_replace_callback(
''/[^/w/d ]/i'',
''_convertAsciOver127toNumericEntitys'', $content);