有没有办法在xml中转义CDATA结束标记?

Jua*_*ano 126 xml escaping cdata

我想知道是否有任何方法可以]]>在xml文档的CDATA部分中转义CDATA结束标记().或者,更一般地说,如果在CDATA中使用某些转义序列(但如果它存在,我想它可能只有在逃避开始或结束令牌时才有意义).

基本上,您是否可以在CDATA中嵌入开始或结束标记,并告诉解析器不要解释它,而是将其视为另一个字符序列.

可能你应该重构你的xml结构或你的代码,如果你发现自己试图这样做,但即使我在过去3年左右每天都在使用xml而且我从来没有遇到过这个问题,我想知道是否有可能.只是出于好奇.

编辑:

除了使用html编码...

S.L*_*ott 167

你必须将你的数据分成几块来隐藏]]>.

这是整个事情:

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

第一个<![CDATA[]]]]>]].第二个<![CDATA[>]]>>.

  • 这应该是公认的答案.*逃避*是一个稍微含糊不清的术语,但这个答案肯定会解决*逃避*的精神.太糟糕了,它不符合OP对*转义*的狭隘概念,因为某种原因任意地要求反斜杠字符. (28认同)
  • 总而言之,转义`]]>`as`]]]]> <![CDATA [>`.长度的5倍...哇.但是,这是一个不常见的序列. (5认同)
  • 5x长度不仅热闹,它甚至不是代码中不常见的序列,这是CDATA的主要用例!假设压缩的JavaScript删除空格,您可以通过索引从名称数组中按名称访问字段,例如"if(fields [fieldnames [0]]> 3)",现在您必须将其更改为"if( fields [fieldnames [0]]]]> <![CDATA [> 3)",这使得使用CDATA的目的无法使其更具可读性,LOL.我想用口头方式打击那些提出CDATA语法的人. (5认同)
  • 那些争论“逃避”含义的人是迂腐的。这就像说你不能调用 `a='&lt;scr'+'ipt&gt;'` 或 `foo.com/bar%20gaz` 转义,只是因为虽然语言上准确,但它不是确切的技术术语。是的,有多个 CDATA 部分,在极少数情况下这很重要。但根据牛津大学的说法,计算中的广义定义是“导致后续字符被不同地解释”。在这种情况下和提到的情况下,会发生。 (2认同)

dda*_*daa 134

显然,这个问题纯粹是学术性的.幸运的是,它有一个非常明确的答案.

您无法转义CDATA结束序列.XML 规范的生产规则20 非常清楚:

[20]    CData      ::=      (Char* - (Char* ']]>' Char*))
Run Code Online (Sandbox Code Playgroud)

编辑:此产品规则字面意思是"CData部分可能包含任何你想要的但是序列']]>'.没有例外."

编辑2:同一部分还写道:

在CDATA部分中,只有CDEnd字符串被识别为标记,因此左尖括号和&符号可能以其字面形式出现; 他们不需要(也不能)使用" &lt;"和" &amp;" 进行转义.CDATA部分无法嵌套.

换句话说,不可能使用实体引用,标记或任何其他形式的解释语法.CDATA部分中唯一解析的文本是]]>,它终止了该部分.

因此,不可能]]>在CDATA部分内逃脱.

编辑3:同一部分还写道:

2.7 CDATA部分

[定义:CDATA部分可能出现在任何可能出现字符数据的地方; 它们用于转义包含字符的文本块,否则这些字符将被识别为标记.CDATA部分以字符串"<![CDATA ["开头,以字符串"]]>":]结束

然后可能存在CDATA部分,可能出现任何字符数据,包括单个CDATA部分的多个相邻CDATA部分.这使得可以分割]]>令牌并将其两部分放在相邻的CDATA部分中.

例如:

<![CDATA[Certain tokens like ]]> can be difficult and <invalid>]]> 
Run Code Online (Sandbox Code Playgroud)

应该写成

<![CDATA[Certain tokens like ]]]]><![CDATA[> can be difficult and <valid>]]> 
Run Code Online (Sandbox Code Playgroud)

  • 这不是一个学术问题.想想包含有关CDATA的讨论的博客文章的RSS提要. (37认同)
  • 我刚刚被这个被咬了,因为我试图将一些压缩的Javascript编码成一个<script>标签,如:`<script>/*<![CDATA [*/javascript to here/*]]>*/</ script >`我的javascript只包括那个序列!我喜欢拆分成多个CDATA部分的想法...... (5认同)
  • 我在现实世界中经历了这一点。在阅读维基百科转储并编写另一个 xml 文件时,我在 [国家运输安全委员会] (https://en.wikipedia.org/wiki/National_Transportation_Safety_Board) 的页面上遇到了这个问题。它包含 _US$&gt;100 百万 (2013)_ 用于信息框中的预算。源 xml 包含“[[美元|美元]]&gt;1亿(2013)”,被读者翻译为“[[美元|美元]]]&gt;1亿(2013)”。作者选择使用 CDATA 来转义文本并失败了。 (5认同)
  • 我的意思是"学术":"有趣的讨论,但没有实际用途".通常,CDATA没有用,它只是一种序列化XML文本的方法,它在语义上等同于使用字符实体转义特殊字符&lt; &GT; 和".字符实体是最简单,最健壮和最通用的解决方案,因此使用它而不是CDATA部分.如果您使用适当的XML库(而不是使用字符串构建XML),您甚至不必考虑它. (4认同)
  • 的确。嗯,我不是一个学术型的人,但正如我在问题中所说,我只是对此感到好奇。老实说,我只会相信你的话,因为我几乎无法理解该规则所使用的语法。感谢您的回答。 (2认同)

Jas*_*ron 15

你没有逃脱,]]>但你通过插入之前逃脱>后,想到这就像在C/Java/PHP/Perl字符串中但只需要在a之前和之后.]]]]><![CDATA[>\>]]

顺便说一句,

S.Lott的回答与此相同,措辞不同.

  • 这种说法给人们错误的想法.这不是**逃避.`]]]]> <![CDATA [>`不是`]的一些神奇序列.`]]]]>`有`]]`字符作为数据,`]]>`结束当前的CDATA部分.`<![CDATA [>`启动一个新的CDATA部分并在其中放入`>`.它们实际上是两个不同的元素,在使用DOM解析器时将被区别对待.你应该知道这一点.这样做的方式类似于`]]]> <![CDATA []>`,除了它在第一个和第二个CDATA中放置`]`和``>`.差异仍然存在. (3认同)
  • 我更喜欢这个措辞.:) (2认同)

Rob*_*ney 7

S. Lott的答案是正确的:你没有对结束标记进行编码,而是在多个CDATA部分中对其进行分解.

如何在现实世界中遇到这个问题:使用XML编辑器创建一个将被送入内容管理系统的XML文档,尝试写一篇关于CDATA部分的文章.你在CDATA部分嵌入代码示例的普通技巧将在这里失败.你可以想象我是如何学到这一点的.

但是在大多数情况下,你不会遇到这个,这就是原因:如果你想将XML文档的文本存储(比方说)作为XML元素的内容,你可能会使用DOM方法,例如:

XmlElement elm = doc.CreateElement("foo");
elm.InnerText = "<[CDATA[[Is this a problem?]]>";
Run Code Online (Sandbox Code Playgroud)

DOM完全合理地逃脱了<和>,这意味着你没有无意中在文档中嵌入了CDATA部分.

哦,这很有趣:

XmlDocument doc = new XmlDocument();

XmlElement elm = doc.CreateElement("doc");
doc.AppendChild(elm);

string data = "<![[CDATA[This is an embedded CDATA section]]>";
XmlCDataSection cdata = doc.CreateCDataSection(data);
elm.AppendChild(cdata);
Run Code Online (Sandbox Code Playgroud)

这可能是.NET DOM的一种特殊情况,但这不会引发异常.抛出异常:

Console.Write(doc.OuterXml);
Run Code Online (Sandbox Code Playgroud)

我猜在幕后发生的事情是XmlDocument使用XmlWriter产生它的输出,并且XmlWriter在写入时检查格式良好.

  • CDATA几乎总能完全避免.我发现那些经常与CDATA斗争的人并不了解他们真正想做的事情和/或他们使用的技术是如何运作的. (2认同)

Tho*_*ger 5

只需更换]]>]]]]><![CDATA[>