何时到CDATA vs. Escape&反之亦然?

时间:2009-06-08 22:49:24

标签: xml escaping cdata

我正在使用从数据库中提取的值创建XML文档。有时候由于遗留实现,我会回调一个值,该值包含一个在未正确转义时无效的字符(例如)。

所以问题就变成了,我应该CDATA还是Escape?某些情况是否更适合于一种情况?

示例:

<Email>foo&bar@domain.com</Email>

我在这里倾向于CDATA。

<Name>Bob & Tom</Name>

我倾向于逃离这里。

我想每次都盲目地避免CDATA',但从性能的角度来看,这似乎是合乎逻辑的选择。这总是比寻找无效的char更快,如果它存在则再包装。

思想?

5 个答案:

答案 0 :(得分:18)

CDATA主要用于IMO,用于人类可读性。就机器而言,除了长度之外,CDATA和转义文本之间没有区别。也许转义版本需要花费更长的时间来处理,但我说也许,因为除非你的应用程序主要是IO绑定的,否则这不应该是一个重要的因素。

人们是否可能正在阅读XML?如果没有,只需让XML解析器执行它所做的事情,不要担心CDATA vs转义文本。如果人们会阅读这个XML,那么CDATA可能是更好的选择。

如果您要使用值为XML的XML元素,那么对于这种情况,CDATA可能是更好的选择。

有关详细信息,请参阅XML常见问题解答When should I use a CDATA Marked Section?

答案 1 :(得分:5)

我见过人们使用CDATA进行上述操作是正常的,并且用于包装不是XML的东西 - 例如JSON或CSS - 这是使用它的更好理由。当人们使用它引用基于元素的标记(如HTML)时会出现问题,然后就会发生混淆。

人们不希望

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

相同
&lt;foo&gt;bar&lt;/foo&gt;

就XML系统而言。

请参阅RSS标签汤,了解逃避级别的恐怖示例。

您还必须确保字符序列']]&gt;'将永远不会出现在你的包装数据中,因为那是终结者。

因此,除非可读性至关重要或者包装非元素标记,否则我建议避免使用CDATA。

答案 2 :(得分:1)

我认为没有真正的区别。我更喜欢使用CDATA来处理所有事情,因为我不必关心要逃脱的角色,我唯一需要注意的是“]]&gt;”在内容中,如果将CDATA打开和关闭标记拆分为多个片段,则允许使用btw。

示例(在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!");

?>

<强>返回

Hello little world!

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

如果你把它放到这样的XML结构中:

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

...将其保存到文件(如test.xml)并使用浏览器打开它,您将看到,浏览器(或任何其他XML应用程序/解析器)将显示正确的输出字符串:< / p>

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

答案 3 :(得分:0)

在以下条件下使用CDATA包装:    如果您怀疑数据并且想要逃避这些数据    数据用于显示,因为那时该应用程序也将进入unescape。    重复地转义相同的数据元素 - 更多的解析和数量逃避会影响表现。

答案 4 :(得分:0)

我认为CDATA会更快 - 它必须扫描结束字符,从头到尾复制并传回 - 一份。 通过读取转义数据,它必须使用缓冲区,在扫描转义字符时附加到缓冲区,当它完成时,将缓冲区转换为字符串并将其传回。 因此,转义将使用更多的内存,并将不得不做一个额外的副本。 虽然您可能只会注意到大量数据和大量事务的差异。因此,如果它的小领域,不要担心它 - 使用它们。