XML DTD中的PCDATA与CDATA

时间:2013-12-09 15:20:08

标签: xml dtd cdata sgml pcdata

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

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

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

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

2 个答案:

答案 0 :(得分:2)

在属性的声明值中使用 CDATA是指属性(字符数据)的实际值,而不是解析它的上下文。另一方面,在解析元素时,我们需要区分character-data-with-no-markup(CDATA)和parsed-character-data-where-delimiters-expected(PCDATA)。

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

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

attribute value specification = attribute value literal | attribute value

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

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

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

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

接下来,属性值文字中实体引用的替换不依赖于属性的声明值。因此,如果您有<!ENTITY foo "bar"><elem attr="&foo;">,则将在可替换字符数据(LIT识别模式)的上下文中解析实体引用&foo;,从而产生<elem attr=bar>。将attr声明为CDATA,NAME或其他任何内容都无关紧要。

<强>更新

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

此处CDATA表示有效属性在扩展实体后必须包含任意字符数据。 如果该属性已声明为NUMBER,则需要包含数字字符(或扩展为数字字符的实体)。

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

答案 1 :(得分:0)

CDATA section就像您在元素中使用的那样,与CDATA attribute type不同。

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