XML DTD中的PCDATA与CDATA

XML DTD中的PCDATA与CDATA,xml,dtd,cdata,sgml,pcdata,Xml,Dtd,Cdata,Sgml,Pcdata,在XMLDTD中——定义元素时,我们使用#PCDATA表示该元素可以包含任何可解析文本。定义属性时,我们使用CDATA表示其值可以是任何字符数据 XML中使用的CDATA是XML解析器无法解析的内容(多字符转义序列)。一致地,当我们使用CDATA定义属性时;解析器不应该解析它。但是,的确如此 那么,为什么不能用PCDATA代替CDATA来定义属性呢 更新-以这种方式保持与SGML向后兼容。SGML中这种命名背后的原因是什么?A,就像您在元素中使用的那样,不同于 您最有可能观察到的解析(如正在解析

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

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

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

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

A,就像您在元素中使用的那样,不同于


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

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

乍一看,这似乎是武断的,但事实并非如此(请参阅和)

在SGML中,属性值规范可以是带引号的(属性值文字)或不带引号的(属性值)

当属性不带引号时,只允许使用名称字符,对于某些声明的值(如NUMBER),可能会进一步限制名称字符

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

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

因此,属性值文本中实体引用的替换不依赖于属性的声明值。因此,如果您有
实体引用
&foo将在可替换字符数据的上下文中解析(LIT识别模式),产生
。无论
attr
是否声明为CDATA、名称或其他内容,这都无关紧要

更新

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

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


在上面的示例中,值为
“&foo;”
的CDATA属性相当于
“bar”
,与值为
“&&48;”
的数字属性相当于
“0”
(即使序列
“&&48;”
包含数字以外的字符).

此项的可能重复项基于您提到的问题的结论……您如何使用CDATA作为属性?这是不可能的。我指的是CDATA用于定义属性类型的情况..而不是CDATA部分..我觉得这有点模棱两可。此CDATA属性类型的工作方式类似于DTD中元素定义的PCDATA类型。为什么使用相同名称的CDATA,PCDATA不是更好吗?@nikel-我不知道为什么属性使用
CDATA
而不是
#PCDATA
。如果存在差异,我不确定它们是什么。我认为
PCDATA
是修改文档实际结构的东西,而
CDATA
是任意文本。使用这个定义,我认为属性
CDATA
是有意义的。属性和节在其CDATA中有不同的转义规则,但它们最终都表示一个不会改变结构的字符串(除了最初存在的字符串)。您所说的“改变文档的实际结构”到底是什么意思?@nikel-请添加其他答案,而不是编辑我的答案。您的编辑是一个完全不同的答案。我的观点是,既然CDATA在解析上下文中已经有了意义,为什么不为属性定义使用一个新名称呢?第二次使用CDATA(在属性定义的情况下)对于第一种情况(元素定义:CDATA元素未被解析)的使用似乎不明确…我理解你的观点。关于标准为什么在两个地方使用相同的关键字的问题应该向SGML作者提问。我们,仅仅是凡人,只能详细说明这个选择如何与CDATA的其他用途保持一致。这就是我问的原因,也许有一些我不知道的东西可以解释这种一致性。我在上面的回答中解释了这种命名的一致性。我理解CDATA在属性方面意味着不同的东西。问题是在两个地方使用同一个词。也许,如果不是CDATA节,而是将它们称为NPCDATA节(非解析字符数据节),这将是最好的。。。
attribute value specification = attribute value literal | attribute value
attribute value literal =
   ( LIT , replaceable character data *, LIT) | 
   ( LITA , replaceable character data *, LITA)