2009-06-08 30 views
12

Estoy creando documentos XML con valores obtenidos de un DB. Ocasionalmente, debido a una implementación heredada, retiraré un valor que contiene un carácter que no es válido cuando no se ha escapado correctamente (&, por ejemplo).¿Cuándo CDATA vs. Escape & Vice Versa?

Entonces la pregunta es, ¿debería CDATA o Escape? ¿Son ciertas situaciones más apropiadas para una frente a la otra?

Ejemplos:

<Email>foo&[email protected]</Email> 

que se inclinaba hacia CDATA aquí.

<Name>Bob & Tom</Name> 

Me inclino por escapar aquí.

Quiero evitar a ciegas CDATA'ing cada vez, pero desde una perspectiva de rendimiento, parece que esa es la opción lógica. Eso siempre será más rápido que buscar un char inválido, y si existe, entonces envuelva.

¿Pensamientos?

Respuesta

16

CDATA es principalmente útil, IMO, para la legibilidad humana. En lo que respecta a una máquina, no hay diferencia entre CDATA y el texto escapado que no sea la longitud, como máximo. Tal vez la versión escapada tarde un poco más en procesarse, pero digo quizás, porque esto no debería ser un factor significativo a menos que su aplicación esté principalmente vinculada a IO.

¿Es probable que las personas lean el XML? Si no, simplemente deje que el analizador XML haga lo que hace y no se preocupe por CDATA contra el texto escapado. Si las personas leerán este XML, quizás CDATA sea la mejor opción.

Si va a tener un elemento XML cuyo valor es XML, entonces en este caso, CDATA puede ser la mejor opción.

Para obtener más información, véase por ejemplo la pregunta del FAQ XML, When should I use a CDATA Marked Section?

+1

CDATA también es más compatible con la red para cadenas más grandes que deben ser escapadas, por lo que debería usarse en la mayoría de los casos en que el archivo XML se transmitirá a través de una red. –

5

que he visto personas usan CDATA de lo anterior, que está bien, y para envolver las cosas que no son XML - como por ejemplo, JSON o CSS, y esa es una mejor razón para usarlo. El problema ocurre cuando las personas lo usan para citar un marcado basado en elementos, como HTML, y luego ocurre la confusión.

La gente no espera

<![CDATA[<foo>bar</foo>]]> 

ser idéntica a

&lt;foo&gt;bar&lt;/foo&gt; 

por lo que los sistemas de XML se refiere.

Consulte la sopa de etiquetas RSS para ver ejemplos del horror de los niveles de escape.

También debe asegurarse de que la secuencia de caracteres ']]>' nunca aparecerá en sus datos envueltos ya que ese es el terminador.

De modo que, a menos que la legibilidad sea primordial o que esté envolviendo el marcado sin elemento, recomiendo evitar CDATA.

0

Envuelva con CDATA en estas condiciones: Si tiene datos dudosos y está tratando de escapar de esos , los datos se utilizan para mostrar, porque entonces esa aplicación también se va a unescape. Escape del mismo elemento de datos repetidamente: más cantidad de análisis & de escape afectarán el rendimiento.

0

Creo que no hay diferencia real. Prefiero usar CDATA para todo porque no tengo que preocuparme por los personajes para escapar y lo único que debo cuidar es el "]]>" en el contenido, que por cierto SI está permitido si se divide la apertura de CDATA y cerrar etiquetas en múltiples fragmentos.

Ejemplo (en PHP)

<?php 

function getXMLContent($content) 
{ 
    if 
    (
     (strpos($content, '<') !== false) || 
     (strpos($content, '>') !== false) || 
     (strpos($content, '&') !== false) || 
     (strpos($content, '"') !== false) || 
     (strpos($content, '\'') !== false) 
    ) 
    { 
     // If value contains ']]>', we need to break it into multiple CDATA tags 
     return "<![CDATA[". str_replace(']]>', ']]]]><![CDATA[>', $content) ."]]>"; 
    } 
    else 
    { 
     // Value does not contain any special characters which needs to be wrapped/encoded/escaped 
     return $content; 
    } 
} 

echo getXMLContent("Hello little world!"); 
echo PHP_EOL . PHP_EOL; 
echo getXMLContent("This <is> a & hard \" test ' for ]]> XML!"); 

?> 

devoluciones

Hello little world! 

<![CDATA[This <is> a & hard " test ' for ]]]]><![CDATA[> XML!]]> 

que si se pone en una estructura XML como esto:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?> 
<test> 
    <![CDATA[This <is> a & hard " test ' for ]]]]><![CDATA[> XML!]]> 
</test> 

... Guardar a un archivo (como test.xml) y ope n con un navegador, verá, que el navegador (o cualquier otra aplicación de XML/parser) que mostrarán la secuencia correcta ouput:

This <is> a & hard " test ' for ]]> XML! 
0

Creo CDATA será más rápida - tiene que explorar en busca de el personaje final, haga una copia de principio a fin y devuélvala - una copia. Al leer datos escapados, tiene que usar un búfer, anexar a él mientras escanea en busca de caracteres escapados y, cuando finaliza, encubrir el búfer a una cadena y devolverlo. Por lo tanto, escapando usará más memoria y tendrá que hacer una copia adicional. Aunque probablemente solo notará una diferencia en grandes conjuntos de datos y un gran número de transacciones. Entonces, si son campos pequeños, no te preocupes, usa cualquiera de los dos.

Cuestiones relacionadas