14

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

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

例子:

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

我倾向于这里的 CDATA。

<Name>Bob & Tom</Name>

我倾向于逃离这里。

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

想法?

4

5 回答 5

21

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

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

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

有关更多信息,请参阅 XML 常见问题解答的问题,我何时应该使用 CDATA 标记部分?

于 2009-06-09T01:04:12.860 回答
5

我已经看到人们将 CDATA 用于上述情况,这是可以的,并且用于包装非 XML 的东西 - 例如 JSON 或 CSS - 这是使用它的更好理由。当人们使用它来引用基于元素的标记(例如 HTML)时,就会出现问题,然后就会发生混淆。

人们不期待

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

等同于

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

就 XML 系统而言。

请参阅 RSS 标签汤了解逃逸关卡的恐怖示例。

您还必须确保字符序列 ']]>' 永远不会出现在您的包装数据中,因为它是终止符。

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

于 2009-06-09T01:18:52.580 回答
1

我认为没有真正的区别。我更喜欢将 CDATA 用于所有内容,因为我不必关心要转义的字符,我唯一需要注意的是内容中的“]]>”,顺便说一句,如果您拆分 CDATA 开头,则允许使用并将结束标签分成多个片段。

示例(在 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 应用程序/解析器)将向您显示正确的输出字符串:

This < is > a & hard " test ' for ]]> XML!
于 2015-10-22T22:07:26.610 回答
0

在这些情况下用 CDATA 包装:如果您有可疑的数据并且您想转义那些 Data is used for display ,因为那时该应用程序也将转义。反复转义相同的数据元素 - 更多的解析和转义将影响性能。

于 2013-09-25T06:36:05.257 回答
0

我认为 CDATA 会更快 - 它必须扫描结束字符,从头到尾制作一个副本并将其传回 - 一个副本。读取转义数据时,它必须使用缓冲区,在扫描转义字符时附加到缓冲区,完成后,将缓冲区转换为字符串并将其传回。因此,转义将使用更多内存,并且必须进行额外的复制。尽管您可能只会注意到大型数据集和大量事务的差异。所以如果它的小领域,不要担心 - 使用任何一个。

于 2016-12-06T11:15:08.800 回答