【问题标题】:What is the prefered way handle "<![CDATA[" in a <![CDATA[ block?在 <![CDATA[ 块中处理“<![CDATA[”的首选方式是什么?
【发布时间】:2011-10-18 03:07:29
【问题描述】:

&lt;![CDATA[]]&gt; 不允许在 &lt;![CDATA[ … ]]&gt; 块内。这是可以理解的。

现在,我必须在 &lt;![CDATA[ … ]]&gt; 块内传输用户输入的数据。恶意用户可能会输入&lt;![CDATA[]]&gt; 或两者。

问题是:处理这种情况的首选方法是什么?

  • 剥离&lt;![CDATA[]]&gt;?
  • 用空格替换它?
  • 向用户发送错误消息?
  • 或者有官方的实际传输方式吗?

【问题讨论】:

  • 为什么要编写自己的 XML 库?已经有很多成熟的了。
  • @Quentin:在服务器和台式机上,确实有足够的库来完成这项工作。但我为嵌入式系统(Android)开发。并且那里需要的库仅从版本 2.2 开始可用。但我们向客户承诺至少 2.0 的兼容性。但我是一个“真正的”程序员,我不介意自己做。接受的答案可能令人惊讶,但有时答案确实是:“你做错了,试试这个替代方案”,我可以接受。我不再使用 CDATA,而是选择编码 &lt;&gt;&amp;"'
  • 请注意,CDATA 内容仅限于编码中可用的字符。数字实体引用 (&nnn;) 可以对整个 Unicode 集进行编码,而不管编码如何,甚至是 ASCII。所以我支持 Martin,改用数字字符引用。

标签: xml xml-serialization cdata


【解决方案1】:

我认为您以错误的方式考虑 CDATA 部分 - CDATA 代表“字符数据”,而 CDATA 语法只是不应被解释为标记的数据块的语法。 CDATA 部分对于将 xml 文档嵌入到另一个 xml 文档中很有用,但是当在文档中包含字符数据(即文本)时,如果它包含在 CDATA 部分中而不是简单地编码为文本数据,则不应改变数据的含义(可能转义了某些字符)。

简而言之,您的应用程序不应该关心数据是否编码为 CDATA。如果您正在编码的文本使用类似 xml 的语法并不太繁重,那么您最好直接转义 &amp;&lt; 字符 - 您的 XML API 可能无论如何都会为您做这件事。例如 XmlNode 的 InnerText 属性将根据需要转义字符。

如果你仍然想使用 CDATA 标签(转义一个大的 xml 片段可能会过度膨胀结果文档的大小)那么你只需要转义代码 CDATA 语法片段(]]&gt;),例如可以这样做只需将]]&gt; 替换为]]]]&gt;&lt;![CDATA[&gt;

【讨论】:

  • 仅当您可以重新设计 XML 应用程序时。无论如何,“XML”比“嵌入在 XML 中的 Base 64 编码数据”更简单,因此这是一个糟糕的主意。
  • @Quentin 我意识到这是一个糟糕的想法并修正了我的答案。
  • 后端团队建议使用&lt;![CDATA[ … ]]&gt;。阅读您的评论,我想知道这是否是个好主意,因为我们正在谈论姓名、地址、电话号码。 &amp; 应该很少出现,&gt; 根本不会出现。除非用户是恶意的并尝试一些 xml 注入。
【解决方案2】:

当您必须包含该字符串时,使用字符引用而不是 CDATA。

【讨论】:

    【解决方案3】:

    从技术上讲,CDATA 部分可以包含另一个起始标记——&lt;![CDATA[——它只是被解释为字符数据。它不能包含的是]]&gt;。通常的方法是在编码时将 CDATA 拆分为用户提供的数据中的]]&gt;。来自Wikipedia

    CDATA 节不能包含字符串“]]>”,因此 CDATA 节不可能包含嵌套的 CDATA 节。使用 CDATA 节对包含三元组“]]>”的文本进行编码的首选方法是使用多个 CDATA 节,方法是在“>”之前拆分每个出现的三元组。例如,要编码“]]>”,可以这样写:

    <![CDATA[]]]]><![CDATA[>]]>
    

    这意味着要在 CDATA 部分的中间编码“]]>”,请将所有出现的“]]>”替换为以下内容:

    ]]]]><![CDATA[>
    

    这有效地停止并重新启动 CDATA 部分。

    [结束维基百科引述]

    看看这是在做什么?实际上,您最终得到的是:

    <![CDATA[ ]] ]]> 
    <![CDATA[ > ]]> 
    

    (为强调而添加了空格。)因此,您将 ]]&gt; 编码为 ]] 旁边的 &gt; ——当您的 XML 处理器在解码过程中将它们重新组合在一起时,您最终会得到]]&gt; 作为字符数据,但 ]]&gt; 从未真正出现在您的 CDATA 部分中。

    但是,在这个时代,您应该没有任何需要担心这一点。无论您使用什么工具/库来创建 XML,都应该为您简单地管理它,如果您将字符数据放入 XML 的元素中,则应该以 XML 库认为合适的方式自动完成到字符数据的转换,所有必要的转义,无需您考虑。

    关注恶意用户数据是件好事,但在这种情况下处理它的最佳方法是正确使用已经有人为您关注的成熟库。

    【讨论】:

    • 你说的这个工具只有android 2.1才有,我要为android 1.6开发。这基本上意味着我必须自己编写工具:-(。所以感谢您真正需要的答案。
    【解决方案4】:

    在 CDATA 部分中,将所有 ]]&gt; 替换为 ]]]]&gt;&lt;![CDATA[&gt;

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-06-04
      • 2021-02-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-08-10
      • 2011-02-16
      相关资源
      最近更新 更多