6

在 XML DTD's - 当定义一个元素时,我们使用#PCDATA 来表示这个元素可以包含任何可解析的文本。在定义一个属性时,我们用 CDATA 来表示它的值可以是任何字符数据。

XML 中使用的 CDATA 是 XML 解析器(多字符转义序列)未解析的内容。一致地,当我们使用 CDATA 来定义属性时;解析器不应该解析它。但是,确实如此!

那么,为什么不能用 PCDATA 代替 CDATA 来定义属性呢?

更新- 这一直保持这种方式与 SGML 向后兼容。在 SGML 中这样命名的原因是什么?

4

2 回答 2

2

当用于属性的声明值时,CDATA 指的是属性的实际值(字符数据),而不是解析它的上下文。另一方面,在解析元素时,我们需要区分不带标记的字符数据 (CDATA) 和预期分隔符的已解析字符数据 (PCDATA)。

乍一看,这似乎是任意的,但事实并非如此(参见此处此处)。

在 SGML 中,属性值规范可以被引用(属性值文字)或不被引用(属性值)。

attribute value specification = attribute value literal | attribute value

当属性不加引号时,只允许使用 NAME 字符,并且对于某些声明的值(例如 NUMBER)可能会进一步限制。

另一方面,属性值 literal的内容是由 LIT/LITA 分隔符(在参考具体语法中分别为双引号和单引号)包围的可替换字符数据序列。

attribute value literal =
   ( LIT , replaceable character data *, LIT) | 
   ( LITA , replaceable character data *, LITA)

可替换字符数据“与 CDATA 类似,但实体引用和字符引用被识别”(Goldfarb,SGML 手册)。

因此,属性值文字中实体引用的替换不依赖于属性的声明值。因此,如果您拥有<!ENTITY foo "bar">并且<elem attr="&foo;">实体引用&foo;将在可替换字符数据的上下文中进行解析(LIT 识别模式),则产生<elem attr=bar>. 是否attr声明为 CDATA、NAME 或其他都没有关系。

更新

不必说必须解析属性中的实体,因为所有属性类型都有相同的解析规则:如果属性值以引号 (LIT) 开头,则实体被识别(可替换字符数据)并且值当找到匹配的结束引号时结束。

这里的 CDATA 意味着一个有效的属性必须包含扩展实体后的任意字符数据。如果该属性被声明为 NUMBER,则需要包含数字字符(或扩展为数字字符的实体)。

在上面的示例中,具有值的 CDATA 属性"&foo;"等价于"bar",与具有值的 NUMBER 属性"&#48;"等价于的方式相同"0"(即使序列 "&#48;"包含数字以外的字符)。

于 2013-12-18T07:42:12.037 回答
0

CDATA 部分,就像您在元素中使用的一样,与CDATA属性类型不同。

您最有可能观察到的解析(如正在解析的实体引用)来自attribute-value normalization

于 2013-12-09T16:40:43.360 回答