4

这是一个有效的(格式良好的)XML 文档吗?

<?xml version="1.0" encoding="UTF-8" ?> 
<outer>
  <inner>&copy;</inner>
</outer>

问题在于 HTML/XHTML“©”实体编码在没有 DTD 或模式来定义它的 XML 文档中是否有效。表达上述内容的另一种方式是这样说:

<?xml version="1.0" encoding="UTF-8" ?> 
<outer>
  <inner>&#169;</inner>
</outer>

这似乎是具有 UTF-8 编码的有效 XML。

但这是否有效:

<?xml version="1.0" encoding="UTF-8" ?> 
<outer>
  <inner><![CDATA[&copy;]]></inner>
</outer>

上面的作者打算向XML解析器表明它应该通过上面的版权符号作为字符串“©” 而不是作为正确的 Unicode 字符。

在这方面我觉得这句话有点令人困惑:'XML 文档的新作者经常误解 CDATA 部分的目的,错误地认为它的目的是“保护”数据在处理过程中不被视为普通字符数据。[但是] 字符数据是字符数据,无论它是通过 CDATA 部分还是通过普通标记表示的。”(来自维基百科

我正在单独查看第二位作者提出的 XML 格式,他将每个标签都包装在 CDATA 部分中,即使标签只能包含数字。

希望 XML 大师可以帮助消除对 CDATA 目的的困惑。

谢谢!

4

3 回答 3

9

CDATA 部分的目的是允许通常在 XML 文档中以特殊方式解释的文字文本。也就是说,看起来像实体引用的东西,或者看起来像 XML 标记的东西。CDATA 部分中的任何内容都可以在没有 CDATA 部分的有效 XML 中;您只需要使用实体引用来编码各种特殊字符,这样它们就不会被视为 XML 标记,而是作为标记值的字符数据。

所以是的,以下是完全有效的,只要它是你想要的:

<?xml version="1.0" encoding="UTF-8" ?> 
<outer>
  <inner><![CDATA[&copy;]]></inner>
</outer>

这里,inner元素的值&copy;是不会被 XML 解析器解释为版权符号的实体引用的值。您还可以执行以下操作:

<?xml version="1.0" encoding="UTF-8" ?> 
<outer>
  <inner><![CDATA[<normally> this looks <like/> &amp; xml </normally>]]></inner>
</outer>

其中inner元素的值为

<normally> this looks <like/> &amp; xml </normally>

要在没有 CDATA 部分的情况下执行此操作:

<?xml version="1.0" encoding="UTF-8" ?> 
<outer>
  <inner>&lt;normally&gt; this looks &lt;like/&gt; &amp;amp; xml &lt;/normally&gt;</inner>
</outer>

它的可读性要差得多,但就 XML 解析器而言是等效的。如果您这样做(假设inner元素被定义为包含字符串而不是 XML 的模式或 DTD),那么您的 XML 解析器将报错:

<?xml version="1.0" encoding="UTF-8" ?> 
<outer>
  <inner><normally> this looks <like/> &amp; xml </normally></inner>
</outer>

因此您使用 CDATA 或实体转义来保护 XML 解析器中的特殊字符,以便 XML 数据的客户端可以获取inner 恰好包含 XML 标记字符的值。

注意:为了清楚起见,上面的示例是格式良好的 XML,但如果架构或 DTD 表明该元素inner包含 xsd:string 或等效项,则它是无效的XML 文档。

不,没有定义为 XML 本身一部分的 HTML 或 XHTML 实体不是有效的 XML,除非它们被定义。您的 XML 解析器将返回错误。

于 2009-03-20T04:41:58.943 回答
5

Eddie给了一个很好的答复,我只是补充了一些他显然没有提到的点。

<?xml version="1.0" encoding="UTF-8" ?> 
<outer>
  <inner>&copy;></inner>
</outer>

不合法(实体“副本”未预定义,在 XML 中只有“lt”、“gt”和“quot”)。

<?xml version="1.0" encoding="UTF-8" ?> 
<outer>
  <inner>&#169;</inner>
</outer>

是完全合法的,并且可能会提供您想要的东西(版权符号)。

<?xml version="1.0" encoding="UTF-8" ?> 
<outer>
  <inner><![CDATA[&copy;]]></inner>
</outer>

也是完全合法的,但会产生完全不同的结果(该元素<inner>将包含六个 Unicode 字符,而不是前面示例中的一个)。

<?xml version="1.0" encoding="UTF-8" ?> 
<!DOCTYPE outer[
<!ENTITY copy "&#169;">
]>
<outer>
  <inner>&copy;></inner>
</outer>

也是合法的,并且给出与第二个示例相同的结果。它可以让您免于输入一些您使用但不容易用键盘/编辑器生成的字符。

<?xml version="1.0" encoding="UTF-8" ?> 
<outer>
  <inner>©</inner>
</outer>

也是合法的(因为 encoding="UTF-8",使用 encoding="US-ASCII",这是不可能的),并给出相同的结果。如果您的键盘/编辑器允许您直接使用此字符。

于 2009-03-20T16:16:44.000 回答
1

XML 解析器会忽略 CDATA 块的内容,因此关于验证和可解析性,您可以将任何您喜欢的内容放入 CDATA。

当然,这也伴随着 CDATA 被视为任意的事实,因此如果您想要在 XML 中使用实际的 ©,这将不起作用。我们假设您计划将 CDATA 的内容加载到 X/HTML 解析器中,就像您可能将图像中的 base64 编码二进制数据块加载到图像解析器中一样。XML 解析器不会尝试从 CDATA 块的内容中获取含义;它也可以像它所说的那样说“foo” &copy;

维基百科的引文似乎确实措辞令人困惑。

于 2009-03-20T04:36:32.840 回答