xml - XML DTD 中的 PCDATA 与 CDATA

标签 xml dtd cdata sgml pcdata

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

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

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

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

最佳答案

当用于属性的声明值时,CDATA 指的是属性的实际值(字符数据),而不是解析它的上下文。另一方面,在解析元素时,我们需要区分无标记字符数据 (CDATA) 和预期的已解析字符数据(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;">实体引用 &foo;将在可替换字符数据(LIT 识别模式)的上下文中进行解析,产生 <elem attr=bar> . attr 没关系声明为 CDATA、NAME 或其他。

更新

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

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

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

关于xml - XML DTD 中的 PCDATA 与 CDATA,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20474113/

相关文章:

c# - 如何使用自定义 XmlResolver 解析 DTD *内部* 的公共(public)标识符?

ios - 如何在我的 NSXMLParser 中实现此方法来提取图像

xml - 如何将 XML 文件解析为 R 数据框?

.net - 没有命名空间的 SelectSingleNode

java - 如何更改 Ant 的 XMLValidate 任务提供的验证 "level"?

php - 如何读取此 xml,获取 "parser error : CData section not finished"

objective-c - 解析 XML CDATA block

java - 当内容高于屏幕高度时,如何让 ListView 和 TextView 作为一个单元滚动?

javascript - 可以使用 PHP 创建文件,但半小时后浏览器无法加载

xsd - XML 是否可能具有有效的模式但没有 XML 文档?