【问题标题】:What is the reason that CDATA even exists?CDATA甚至存在的原因是什么?
【发布时间】:2010-12-15 09:54:34
【问题描述】:

我经常看到人们在这里提出与 XML/XSLT 相关的问题,这些问题的根源在于无法掌握 CDATA 的工作原理(例如 this one)。

我想知道 - 为什么它首先存在?不是 XML 不能没有它,你可以放入 CDATA 部分的所有内容都可以表示为“native”(XML 转义)。

我很欣赏 CDATA 可能会使生成的文档更小,但让我们面对现实吧 - XML 无论如何都是冗长的。例如,通过压缩可以更轻松地实现小型 XML 文档。

对我来说,CDATA 打破了标记和数据的清晰分离,因为您可以拥有肉眼看起来像标记的数据,我认为这是一件坏事。 (这甚至可能是鼓励人们不充分地将字符串处理或正则表达式应用于 XML 的原因之一。)

那么:使用 CDATA 有什么好的理由?

【问题讨论】:

    标签: xml xslt cdata


    【解决方案1】:

    CDATA 部分只是为了方便人类作者,而不是为程序。它们的唯一用途是使人类能够轻松地包括例如XHTML 页面中的 SVG 示例代码,无需仔细地将每个 < 替换为 < 等等。

    这对我来说是预期用途。不要使生成的文档小几个字节,因为您可以使用< 而不是<

    还再次从上面获取示例(xhtml 中的 SVG 代码),这使我可以轻松检查 XHTML 文件的源代码,只需复制粘贴 SVG 代码,而无需再次替换 < <

    【讨论】:

    • 我认为这取决于您是使用文本编辑器来操作 XML 还是更合适的工具(如 DOM API)。不过,我理解方便的论点。
    • 另外 - 将 SVG 代码插入 X(HT)ML 文档的 CDATA 部分以某种方式违背了目的,不是吗?我的意思是 - 它会将格式完美的 XML 降级为纯文本数据……
    • @Tomalak 完全正确。这就是我所说的方便人类的意思。如果有人手动编辑一些 xml。
    • cdata 中的@svg 违背:目的:嗯,不,这不是为什么?我的意思是一个讨论 SVG 的页面,因此必须显示一些示例 svg 代码,而不是显示 svg。在这里,cdata-sections 可以轻松包含 svg 代码而无需重新格式化
    【解决方案2】:

    对我来说,CDATA 只是懒惰的另一个词。当我开始使用 XML 时,我使用它,但现在我总是转换数据。

    我能想到的最好理由是方便。尤其是当您使用 XML 作为某种形式的包装器,将数据从一个系统传输到另一个系统时,在这种情况下,您可能会遇到以下情况。

    创建 XML 包装器
    将数据转换为 XML
    将数据放入包装器
    向接收者发送 XML
    将 XML 拆分为 XML + XML 中的数据
    将 XML 中的数据转换为数据

    而使用 CDATA 将导致不需要额外的转换步骤。

    另一种用法是嵌入数据,而不必关心嵌入数据中的不同命名空间。但这并不是一个很好的使用方式。

    我发现了另一个使用 CDATA 的好方法的例子,我应该想到的。当您需要在 XML 文件中嵌入代码时,该代码不应该被转换,否则它将无法工作和/或不容易阅读。

    【讨论】:

    • 我不同意“不需要额外的转换步骤”。您仍然必须确保内容不包含]]>
    • 在这种情况下,这几乎不能算作转换。但你仍然是对的。
    【解决方案3】:

    MXML 演示了 CDATA 标记的大量使用。我喜欢 MXML 的一件事是它是有效的 XML,这意味着我可以做一些有用的事情,例如使用转换从不同的 XML 文件以编程方式生成 flash 小部件,并根据模式验证 MXML。

    CDATA 标记在 MXML 中很有用,因为它们可以在 MXML 文件中定义 ActionScript 脚本块,允许我将 ECMA 类型的脚本语言(使用 > 和

    编辑:

    我想组合 MXML 和 ActionScript 的另一种选择是以组合 HTML 和 Javascript 的方式组合它们,即将脚本包装在脚本块内的 XML 注释标记中,并选择使用 CDATA由 MXML 编译器的开发人员制作。我想推理可能更多地与编辑有关,因为 MXML 编辑器根据模式验证您的代码以检查语法并提供上下文帮助,以及解析您的动作脚本代码以获得语法和上下文帮助。在编辑器中使用 CDATA 允许它同时执行并区分 XML cmets 和脚本块。

    【讨论】:

      【解决方案4】:

      我相信 CDATA 旨在允许原始二进制数据:只要它不包含“]]>”,那么 CDATA 部分中的任何内容。这确实使它有别于普通的 XML,并且应该加快解析速度(并否定全文编码的必要性,从而提供第二次性能提升)。 实际上,事实证明,人们没有逃避结束序列并且几个早期的解析器被各种破坏,所以现在大多数只是对二进制数据使用文本编码,使得 CDATA 部分有点毫无意义,是的。

      编辑: 请注意,这个答案实际上是错误的,正如 Tomalak 在 cmets 中指出的那样。我没有删除它,因为我知道还有其他人认为原始二进制文件在 CDATA 中是可以接受的,这可能会消除这个小小的误解。

      【讨论】:

      • 但 CDATA 表示字符数据,我怀疑您是否可以放入在 XML 中非法的原始字节序列。
      • 哦,是的,你可以!不过,二进制数据往往会破坏链中的其他东西!仍然使用 CDATA 的主要原因是保留文本格式,如换行符、制表符和空格序列,在解析普通制表符时会丢失。
      • 规范 (w3.org/TR/REC-xml/#sec-cdata-sect) 说 CData 可以包含字符 (w3.org/TR/REC-xml/#charsets)。抱歉,但这看起来不像是允许我使用二进制文件。也许有一些奇怪的 XML 解析器允许它,但它肯定不是它的本意。
      • @sinibar:我建议你把这个答案写成一个社区维基(你可以在编辑模式下这样做)。无论您是否指出错误,有些人都会对“错误”的答案投反对票。在 wiki 模式下,这至少不会造成任何声望损失。
      • +1,因为您选择了错误的答案并将其转化为有用的信息
      【解决方案5】:

      如有疑问,check the spec:

      2.7 CDATA 部分

      [定义:CDATA 段可能出现在字符数据可能出现的任何地方;它们用于转义包含字符的文本块,否则这些字符会被识别为标记。

      【讨论】:

      • @NickFitz:我知道基本事实。 ;-) 我在问 CDATA 相对于 XML 转义的 好处 是什么。
      • 规范告诉你:它们用于转义包含字符的文本块,否则这些字符会被识别为标记。这样做的必然结果是,当由于某种原因使用实体转义标记字符不切实际、不可能或不希望时,可以使用它们。因此,好处是 CDATA 部分提供了转义的替代方法。设计实际用例留给读者作为练习;-)
      • 读者,这是Tomalak提出的练习。 :-P
      【解决方案6】:

      当您想为某些 XML 定义架构但其中一部分超出您的控制范围并且您无法确保它符合架构或不会破坏 XML 时,CDATA 部分非常有用。

      我经常不得不使用具有 HTML 输出的遗留系统,这些输出通常不是格式良好的 XHTML,我可以附加一个模式,以确保 XML 的结构正确,但有一个标签,它只包含一个 CDATA 部分,用于容纳潜在的CDATA 中的 HTML 错误。

      这不是一种常见的用法,但当您不希望其他人的松散编程破坏您的系统时,它肯定有它的用途。

      【讨论】:

      • 但是您可以只使用 HTML 输出作为节点值,它们同样可以正常工作,只是它们显示为 XML 转义。
      • 是的,但这会导致必须转换为转义 HTML 然后再次退出的性能成本,这在许多用例中可能很小,但在传输机制中,尤其是在高负载的传输机制中,它可能很重要.另外,正如我强调的那样,在使用遗留系统时,假设它们可以逃脱字符是很危险的,更不用说它们会始终如一地。
      【解决方案7】:

      我不知道这会有多大帮助,但我也会把它扔进去:

      其中一个问题是 XML 开发人员有几个不同的阵营,其中一些人将 XML 视为 数据 的表示,而另一些人则将其视为以以文档为中心 方式。 (XML 的美妙之处在于它对两者都适用。)

      那些将 XML 视为数据表示的人(其中 XML 经常由工具生成和使用,而人类只参与故障排除)将认为 CDATA 部分没有什么价值,因为它不会使他们的工具有所不同,而那些将 XML 用于更多以文档为中心的目的的人可能会发现 CDATA 部分更有用。

      【讨论】:

        【解决方案8】:

        PCDATA - 已解析的字符数据,这意味着输入的数据将被解析器解析。

        CDATA - 在 CDATA 元素之间输入的数据不会被解析器解析。也就是说,CDATA 部分中的文本将被解析器忽略。因此,恶意用户可以使用这些 CDATA 元素向应用程序发送破坏性数据。

        CDATA 部分以<![CDATA[ 开头,以]]> 结尾。

        不能出现在 CDATA 中的唯一字符串是]]>

        我们使用 CDATA 的唯一原因是:像 Javascript 代码这样的文本包含很多 <, & 字符。为了避免错误,可以将脚本代码定义为 CDATA,因为单独使用 < 会产生错误,因为解析器会将其解释为新元素的开始。类似地,& 可以被解析器解释为字符实体的开始。

        【讨论】:

        • 还有一个重要的东西不能放在CDATA中。它是 XML 字符集中不可用的每个字符。在 CDATA 之外,任何字符都可以用 &xxx; 转义。即使在 ASCII 编码的 XML 中,您也可以访问完整的 unicode 字符。但是在 CDATA 中,您会遇到 XML 字符集。我认为像 \r 这样的一些字符在 CDATA 中也是无效的。 CDATA 不是一个好的转义方法。
        【解决方案9】:

        这是为什么/何时您可能想要使用 CDATA 的具体示例

        去掉 CDATA,这个简单的 SVG 将无法被浏览器解析:

        <?xml version="1.0" encoding="UTF-8"?>
        <svg version="1.1"
            baseProfile="full"
            xmlns="http://www.w3.org/2000/svg"
            xmlns:xlink="http://www.w3.org/1999/xlink"
            xmlns:ev="http://www.w3.org/2001/xml-events"
            >
        
        <title>CDATA</title>
        
        <style type="text/css"><![CDATA[
        
        /**
         * Imagine you mention this element <foo> in a comment… or use the & sign.
         * Then…
         *
         * If this weren't wrapped into CDATA (mind both the starting and closing
         * tags), then the browser would fail to parse the file correctly. For example:
         *
         * Firefox would fail with this:
         * > XML Parsing Error: mismatched tag. Expected: [foo's closing tag].
         *
         * Chrome and Safari would fail with this:
         * > This page contains the following errors:
         * > error on line 22 at column 9: Opening and ending tag mismatch: foo line 0 and style
         */
        
        ]]></style>
        
        
        <text x="20" y="60" font-size="60">Hello</text>
        
        <script><![CDATA[
        
        // <text>
        // see comment in the CSS, because it's the same situation here.
        
        ]]></script>
        </svg>
        

        这是一个 SVG 文件,但您应该对任何 XML 文件采取同样的预防措施。

        【讨论】:

        • 您可以对所有这些字符串值进行 XML 转义,这样会很好。 CDATA 这里没有需要。对于人工编辑来说,这是一个“值得拥有”的功能。
        • 很公平——为了精确起见,将“需要”一词编辑为“可能想要使用”。即便如此,我仍会争辩说,采取防御措施,让忘记逃离实体不会破坏文件,是要走的路。
        • 这个问题确实是从 DOM API 的角度写出来的,而不是从人类编辑的角度。我完全明白为什么它很方便。
        猜你喜欢
        • 1970-01-01
        • 2018-12-16
        • 2017-04-10
        • 2013-05-21
        • 2015-12-08
        • 1970-01-01
        • 2017-06-22
        • 2020-10-20
        • 1970-01-01
        相关资源
        最近更新 更多