Me preguntaba si hay alguna forma de escapar de un token final CDATA ( ]]>
) dentro de una sección CDATA en un documento xml. O, más generalmente, si hay alguna secuencia de escape para usar dentro de un CDATA (pero si existe, supongo que probablemente tendría sentido escapar de los tokens de inicio o fin, de todos modos).
Básicamente, ¿puede tener un token de inicio o fin incrustado en un CDATA y decirle al analizador que no lo interprete sino que lo trate como una secuencia de caracteres más?
Probablemente, debería refactorizar su estructura xml o su código si intenta hacerlo, pero a pesar de que he estado trabajando con xml a diario durante los últimos 3 años más o menos y nunca he tenido este problema, Me preguntaba si era posible. Solo por curiosidad.
Editar:
Aparte de usar la codificación html ...
>
como>
dentro programable CData para asegurar incrustado]]>
no se analiza como CDEnd. Simplemente significa que es inesperado y que&
PRIMERO debe codificarse&
también para que los datos puedan decodificarse correctamente. Los usuarios del documento también deben saber decodificar este CData. No es desconocido ya que parte del propósito de CData es contener contenido que un consumidor específico entiende cómo manejar. Tal CData simplemente no puede ser interpretado correctamente por ningún consumidor genérico.CDATA
fue diseñado para permitir cualquier cosa : se usan para escapar de bloques de texto que contienen caracteres que de otro modo se reconocerían como marcado. Eso implicaCDATA
también, ya que también es marcado. Pero, de hecho, no necesita la doble codificación que implicaba.]]>
es un medio aceptable para codificar aCDEnd
dentro de aCDATA
.Respuestas:
Claramente, esta pregunta es puramente académica. Afortunadamente, tiene una respuesta muy definitiva.
No puede escapar de una secuencia final de CDATA. La regla de producción 20 de la especificación XML es bastante clara:
EDITAR: Esta regla del producto significa literalmente "Una sección de CData puede contener lo que desee PERO la secuencia ']]>'. Sin excepción".
EDIT2: La misma sección también lee:
En otras palabras, no es posible utilizar referencias de entidades, marcas o cualquier otra forma de sintaxis interpretada. El único texto analizado dentro de una sección CDATA es
]]>
, y termina la sección.Por lo tanto, no es posible escapar
]]>
dentro de una sección CDATA.EDITAR3: La misma sección también lee:
Entonces puede haber una sección CDATA en cualquier lugar donde puedan aparecer datos de caracteres, incluidas múltiples secciones CDATA adyacentes en lugar de una sola sección CDATA. Eso permite dividir el
]]>
token y colocar las dos partes en secciones adyacentes de CDATA.ex:
debe escribirse como
fuente
<script>/*<![CDATA[*/javascript goes here/*]]>*/</script>
y mi javascript incluye solo esa secuencia! Me gusta la idea de dividir en múltiples secciones CDATA ...[[United States dollar|US$]]>100 million (2013)
que fue traducida[[United States dollar|US$]]>100 million (2013)
por el lector y el escritor optó por usar CDATA para escapar del texto y falló.Tienes que dividir tus datos en pedazos para ocultar el
]]>
.Aquí está todo:
<![CDATA[]]]]><![CDATA[>]]>
El primero
<![CDATA[]]]]>
tiene el]]
. El segundo<![CDATA[>]]>
tiene el>
.fuente
]]>
como]]]]><![CDATA[>
. 5 veces la longitud ... wow. Pero entonces, es una secuencia poco común.No se escapa del
]]>
pero se escapa>
después]]
insertando]]><![CDATA[
antes del>
, piense en esto como una\
cadena C / Java / PHP / Perl, pero solo se necesita antes>
y después de a]]
.Por cierto,
La respuesta de S.Lott es la misma, simplemente redactada de manera diferente.
fuente
]]]]><![CDATA[>
no es una secuencia mágica para]]>
.]]]]>
tiene]]
caracteres como datos y]]>
finaliza la sección CDATA actual.<![CDATA[>
inicia una nueva sección CDATA y la coloca>
. En realidad, son dos elementos diferentes y serán tratados de manera diferente cuando se trabaje con un analizador DOM. Deberías ser consciente de eso. Esta forma de hacerlo es similar]]]><![CDATA[]>
, excepto que incluye]
el primer]>
CDATA y el segundo. La diferencia permanece.La respuesta de S. Lott es correcta: no codifica la etiqueta final, la divide en varias secciones CDATA.
Cómo resolver este problema en el mundo real: utilizando un editor XML para crear un documento XML que se incorporará a un sistema de gestión de contenido, intente escribir un artículo sobre las secciones CDATA. Su truco habitual de incrustar ejemplos de código en una sección CDATA le fallará aquí. Puedes imaginar cómo aprendí esto.
Pero en la mayoría de las circunstancias, no encontrará esto, y he aquí por qué: si desea almacenar (por ejemplo) el texto de un documento XML como el contenido de un elemento XML, probablemente usará un método DOM, por ejemplo:
Y el DOM escapa razonablemente <y el>, lo que significa que no ha incrustado inadvertidamente una sección CDATA en su documento.
Ah, y esto es interesante:
Esta es probablemente una ideosincrasia de .NET DOM, pero eso no arroja una excepción. La excepción se lanza aquí:
Supongo que lo que sucede debajo del capó es que el XmlDocument está utilizando un XmlWriter para producir su salida, y el XmlWriter verifica la buena forma a medida que escribe.
fuente
simplemente reemplace
]]>
con]]]]><![CDATA[>
fuente
Aquí hay otro caso en el que se
]]>
debe escapar. Supongamos que necesitamos guardar un documento HTML perfectamente válido dentro de un bloque CDATA de un documento XML y la fuente HTML tiene su propio bloque CDATA. Por ejemplo:el sufijo CDATA comentado debe cambiarse a:
ya que un analizador XML no sabrá cómo manejar los bloques de comentarios de JavaScript
fuente
]]>
con]]]]><![CDATA[>
todavía se aplica aquí. El hecho de que sea JavaScript o esté comentado no es importante.En PHP:
'<![CDATA['.implode(explode(']]>', $string), ']]]]><![CDATA[>').']]>'
fuente
Una forma más limpia en PHP:
No olvide utilizar un str_replace seguro para múltiples bytes si es necesario (no latin1
$string
):fuente
No creo que interrumpir CDATA sea un buen camino a seguir. Aquí está mi alternativa ...
Úselo
]
para la secuencia de escape seguida del valor hexadecimal de su personaje. Como en el&#xhhhh;
=>]<unicode value>;
De esta manera, si intenta grabar
]]>
su codificación, fn producirá lo]005D;]005D;]003E;
que está bien en CDATA.Es mejor que escapar por nombre de entidad, porque esos no están decodificados cada vez en su aplicación y es posible que tenga diferentes prioridades para escapar de entidades con ampersand frente a escapar de otros caracteres / secuencias. Como resultado, tiene más control sobre el contenido de CDATA.
fuente
Ver esta estructura:
Para las etiquetas CDATA internas, debe cerrar con en
]]]]><![CDATA[>
lugar de]]>
. Simple como eso.fuente