我正在使用从数据库中提取的值创建XML文档。有时候由于遗留实现,我会回调一个值,该值包含一个在未正确转义时无效的字符(例如)。
所以问题就变成了,我应该CDATA还是Escape?某些情况是否更适合于一种情况?
示例:
<Email>foo&bar@domain.com</Email>
我在这里倾向于CDATA。
<Name>Bob & Tom</Name>
我倾向于逃离这里。
我想每次都盲目地避免CDATA',但从性能的角度来看,这似乎是合乎逻辑的选择。这总是比寻找无效的char更快,如果它存在则再包装。
思想?
答案 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>]]>
与
相同<foo>bar</foo>
就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会更快 - 它必须扫描结束字符,从头到尾复制并传回 - 一份。 通过读取转义数据,它必须使用缓冲区,在扫描转义字符时附加到缓冲区,当它完成时,将缓冲区转换为字符串并将其传回。 因此,转义将使用更多的内存,并将不得不做一个额外的副本。 虽然您可能只会注意到大量数据和大量事务的差异。因此,如果它的小领域,不要担心它 - 使用它们。