2009-06-08 102 views
12

我使用从数据库中提取的值创建XML文档。有时由于遗留实现,我会撤回一个包含char的值,如果没有正确转义,该值将无效(例如,&)。何时CDATA与逃脱和副Versa?

所以问题变成了,应该是CDATA还是Escape?某些情况是否适合一个人而不是另一个?

例子:

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

我对CDATA瘦这里。

<Name>Bob & Tom</Name> 

我会倾向于逃避在这里。

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

想法?

回答

16

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

人们可能正在阅读XML吗?如果没有,只需让XML解析器执行它的操作,不用担心CDATA与转义文本。如果人们会阅读这个XML,那么CDATA可能是更好的选择。

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

欲了解更多信息,请参见例如XML FAQ的问题,When should I use a CDATA Marked Section?

+1

CDATA对于需要转义的较大字符串也更具网络友好性,因此在大多数情况下,XML文件将通过网络传输时应使用IMO。 – 2014-03-10 20:48:48

5

我见过的人使用CDATA的是OK的上方,用于包装的东西是不属于XML - 如例如JSON或CSS - 这是使用它的更好理由。当人们用它来引用基于元素的标记(如HTML)时会发生问题,然后发生混淆。

人们不指望

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

是相同

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

尽可能XML系统的关注。

查看RSS标签汤的逃跑层次恐怖的例子。

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

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

0

总结与CDATA在这些条件: 如果你有doubtfull数据和你thnking逃避那些 数据用于显示,因为当时该应用程序也要去UNESCAPE。 重复转义相同的数据元素 - 更多数量的解析&转义会影响性能。

0

我认为没有真正的区别。我更喜欢使用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)和ope ñ它与浏览器,你会看到,浏览器(或任何其他XML应用程序/解析器)会告诉你正确的输出中的字符串:

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

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