CDATA部分真的是不必要的吗?

4
这个问题是因为开发者Michael Rys强烈拒绝将CDATA段解析到FOR XML PATH中而引起的,因为"存储的数据中没有语义差异。" 我已经在CDATA节点中存储了HTML片段和其他需要使用特殊或笨拙字符的内容。然而,我不觉得有资格挑战Rys的争议性说法,因为在我使用CDATA进行方便时,从技术上讲他是正确的。
真正让我困扰的是,当开发者上网寻求如何使用FOR XML PATH呈现CDATA段的建议时,回答者不断地指导他们使用FOR XML EXPLICIT,这是Rys所称的“来自地狱的查询”XML渲染方法。 如果我们确实可以在任何人可以建议的每种用例中都不使用CDATA,那么我想我们应该停止抱怨并从此拒绝使用CDATA。但是,如果有明确定义的情况下CDATA是必不可少的,Rys已经承诺将其纳入到FOR XML PATH中,在这个问题的最顶层链接中。
那么问题来了,CDATA部分真的是过去的遗物吗?还是Rys应该让FOR XML PATH允许CDATA解析?而且,与此同时,有没有什么方法可以让FOR XML PATH返回CDATA部分?
4个回答

3

CDATA部分是不必要的。它们不是“过去的遗物”,因为它们一直都是不必要的。

这并不意味着它们没有用处。看看几乎任何编程语言或库,你都能找到许多你可以不用的东西,因为它们在语义上等价于其他东西,但如果有一个人坐在那里写这些东西,它们就很有用。

事实上,即使使用程序化生成,也可以采取相反的方法,对每个c-data使用CDATA部分(膨胀,但在其他地方可能会有效率提升)。

FOR XML PATH不涉及人类需要编写内容。它是从SQL查询结果中产生有效XML的一种方式。(这也不是解析CDATA部分的问题,而是产生它们的问题-一个不同的问题)。

当你想要真正精细控制时,你不能真正抱怨FOR XML EXPLICIT是替代品- FOR XML EXPLICIT有时很难使用的原因恰恰是因为它给了你真正精细的控制。实际上,考虑一下,如果他们先添加了对CDATA部分的支持,然后又添加了支持其他每个看起来同样重要的微调和配置选项的支持,那么FOR XML EXPLICIT成为更直接的选择需要多长时间呢?

有四种情况下CDATA很有用:

  1. 你坐在键盘前亲自输入这些内容。
  2. 你正在处理混合不同技术、不同时间设计的不同标准,并将由不同解析器以不同方式解释的东西(例如嵌入到XHTML中的javascript-虽然这里不是100%必要,但否则做起来很麻烦)。
  3. 你试图使用某个不理解XML的东西解析XML。
  4. 你试图使用基于允许低级访问并区分CDATA部分和其他字符数据的解析器构建的东西,并不恰当地使用该低级访问。

有趣的是,这四种情况也是禁止接受CDATA部分的四种情况。

第1种情况在这里不适用,因为它不是人类生成的代码。 第2种情况可能适用于此,如果你正在做一些非常疯狂的事情。坦白说,缺少CDATA部分是你最不用担心的问题;在查询中切换到生成更简单的XML,然后在其他地方进行转换。 第3种情况可能适用于此,但如果确实如此,就不应该向SQL人员抱怨,而应该向不将&lt;example&gt;<![CDATA[<example>]]>视为相同的损坏XML解析器抱怨。 第4种情况可能适用于此,但再次向编写有错误代码的人抱怨,而不是向SQL人员抱怨。


一个有趣的观点,我理解你的想法。为了更好地理解,我们的前端开发团队要求我重新设计一些定制客户端API的元素,该API将我们的一些信息呈现为XML模式。其中一些数据是草根AJAX/HTML/CSS/ECMAScript类型设计师通常会放入CDATA中的数据。我愿意说这是不可能的,但我只是想知道我是否不合理。 - One Monkey
这种方式不可行(你可以使用EXPLICIT),但也没有必要,因为对于解析的工具AJAX类型的编码器来说,它看起来是相同的(XHR),即使他们在文本编辑器中以这种方式编写会更不愉快。另一种看待它的方式-如果您很高兴XML标准在某种程度上使事情变得方便,为什么要抱怨别人利用XML标准以不同的方式使事情变得方便呢? - Jon Hanna
经过深思熟虑,我认为,尽管这在理论上是完全合理的,但现实情况却会给我们带来麻烦。本质上,我编写的SQL语句中有许多节点对于FOR XML PATH非常适用,但只有几个引起争议。该SQL语句需要易于他人阅读和修改,并且它提供了我们网站应用程序功能的微小但至关重要的部分。维护FOR XML EXPLICIT查询的时间成本不值得。但是,您无法阻止最终用户在自由文本字段中写入“<Like>Angle<Brack>ets”等内容,这可能会引起问题。 - One Monkey
为什么会引起问题?如果它被放入数据库字段中,那么查询将以某种方式转义它(即CDATA部分或&lt;等),如果两者都不是,则将是一个缺陷。 - Jon Hanna
我想是这样。健康的偏执有时会以不合逻辑的方式使你感到焦虑。我知道你是对的,但我还是忍不住想知道...所以我想我们已经找到了CDATA的真正目的,那就是过度焦虑的开发者的安全保障。 - One Monkey
在问题发生之前寻找问题总是值得的。但在这种情况下,值得注意的是,在某个抽象层次上,CDATA部分根本不存在。现在,如果读取XML的某些内容旨在将我们带到那个层次,而无法解析它们-那就是一个问题-但是如果生成XML的某些内容不会,那么在我们应该担心的抽象层面上,这并不重要。 - Jon Hanna

2

CDATA节段在以下情况下非常有用:如果你不关心其中的数据语义(即,你不需要解析它,只是一串字符),并且你不希望转义其中任何XML标记。

根据 w3 的定义:

CDATA节段可以出现在任何可能出现字符数据的地方;它们用于转义包含会被识别为标记的字符块的文本。

来自 维基百科 的说明:

编写XML文档的新手往往会误解CDATA节段的目的,错误地认为它的目的是“保护”数据,以免在处理过程中被视为普通字符数据。一些用于处理XML文档的API确实提供了独立访问CDATA节段的选项,但这些选项超越了XML处理系统的正常要求,并且仍然不改变数据的隐含含义。无论是使用CDATA节段还是普通标记,字符数据都是字符数据。

CDATA节段对于在XML文档中将XML代码编写为文本数据非常有用。例如,如果你想使用XSL排版一本书,解释如何使用一个XML应用程序,那么出现在书中自身的XML标记将在源文件中以CDATA节段的形式编写。但是,CDATA节段不能包含字符串“]]>”,因此CDATA节段中嵌套CDATA节段是不可能的。使用CDATA节段来编码包含三元组“]]>”的文本的首选方法是通过在“>”之前拆分每个三元组出现的位置,并使用多个CDATA节段。例如,要对“]]>”进行编码,则应编写:


在我看来,那似乎是有效的...无论如何。 - One Monkey
@One Monkey - 我想补充一点,在 大多数 情况下,Michael Rys 是正确的。CDATA 部分通常被误用。如果你需要查询它,那么它就不应该在 CDATA 中。 - Oded
这是一个真正的问题,我很乐意采取最好的方案。我真的很好奇知道人们的想法或他们能想出什么。 - One Monkey
@One Monkey - 我不怀疑问题或你的意图。我的回答是真诚给出的... - Oded

1
看到有人用这样的随意方式抛弃标准中非常有价值的部分,实在是很有趣。并不是每个人都会将XML用于几百个字符的HTML或下拉列表中的项目。
我们中的一些人实际上正在使用XML来交换数据,非常复杂的数据,例如CCD、CDA CDR等,这些都是医疗领域的标准文档格式,并且随着奥巴马医改的推行变得越来越重要。这些文档结构的一部分包含附件,例如DiCOM图像、PDF和其他二进制数据,解析器不应读取这些内容,这就是CDATA定义存在的原因。
为什么我要承担解析器读取嵌入在CCD文档中的3兆字节DiCom图像的开销?为什么我必须在原始数据中分离文档,而它又是XML标准的一部分?我希望能够使用XML定位和恢复文档及其内容。
这让我感到困惑,为什么你们会支持解析本意不是要被引擎解析的数据。如果引擎看到 CDATA 就忽略它,非常简单。而且一些人认为不需要它的争论是无关紧要的。它是标准的一部分,应该得到维护。如果他们想要添加一个“功能”,就用选项来支持默认行为。请停止解析 CDATA 并忽略它。

0

你说得很对,CDATA在许多情况下都是必不可少的,它们是XML标准的一部分,应该被每个XML操作工具/方法支持。但问题是微软通常不关心...你知道的,“640kB应该足够每个人使用”的做法。

编辑:关于FOR XML EXPLICIT - 这是生成精确格式化XML数据的最佳方法。是的,语法看起来有点痛苦和混乱,但一旦你使用了几次,你会欣赏它的美丽和强大。


1
当这些工具是生成而不是解析时,它们绝对不应该“被每个XML操作工具/方法支持”。这就像说我们不应该编写不使用反射的C#程序,因为它在标准中,或者编写不执行广播的Internet软件,因为它在TCP/IP标准中。解析器必须处理CDATA,生产者可以根据需要自由处理。事实上,解析器必须同时处理CDATA和其他字符内容的事实是XML标准所做出的承诺,这意味着生产者可以以这种方式自由处理。 - Jon Hanna

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接