译者:裘强 (qqiu@yeah.net)
4. 物理结构
4.1 字符和实体引用
4.2 实体声明
4.2.1 内部实体
4.2.2 外部实体
4.3 已析实体
4.3.1 文本声明
4.3.2 格式正确的已析实体
4.3.3 实体中的字符编码
4.4 不被识别
4.4.2 被包含
4.4.3 进行验证时被包含
4.4.4 被禁止
4.4.5 作为常量被包含
4.4.6 通知
4.4.7 不处理
4.4.8 作为参数实体被包含
4.5 内部实体置换文本的构建
4.6 预定义实体
4.7 记法声明
4.8 文件实体
[定义:一个 XML 文件可能包含一个或多个存储单元。它们被称为实体(entity);它们都具有内容并且都用名字进行标识(除了文件实体,见下,和外部 DTD 子集之外)。] 每一个 XML 文件有一个称为文件实体的实体,它作为 XML 处理器处理的起点并可能包含了整个文件。
实体可以是已析的或未析的。[定义:已析实体(parsed entity)的内容被称为它的置换文本;此文本被看成是文件整体的一部分。]
未析实体(unparsed entity)是一种资源,其内容可以是也可以不是文本,并且,如果是文本的话,可以不是 XML 文本。每一个未析实体有一个相关联的用名字标识的记法。除了要求 XML 处理器能向应用提供实体和记法的标识符之外,XML 对未析实体的内容不作任何限制。]
已析实体以实体引用的方式使用名字来调用;未析实体用 ENTITY 或 ENTITIES 属性中给出的名字调用。
[定义:普通实体(general entity)是那些在文件内容中使用的实体。在本规范中,普通实体有时用未修饰的术语entity来表示。] [定义:参数实体是用于 DTD 内的已析实体。]这两类实体用不同形式的引用,在不同的上下文中识别。另外,它们使用不同的名字空间;具有相同名字的参数实体和普通实体是两个截然不同的两个实体。
4.1 字符和实体引用(Character and Entity References)
一个字符引用引用 ISO/IEC 10646 字符集中的一个字符。例如不能用输入设备直接输入的字符。
字符引用
[66] CharRef ::= '' [0-9]+ ';'
| '' [0-9a-fA-F]+ ';' [WFC: 合法字符]
格式正确性约束: 合法字符 用字符引用引用的字符必须匹配 Char 产生式。
如果字符引用以 "" 开头,直到终结 ; 的数字和字母提供了某字符在 ISO/IEC 10646 中代码的一个十六进制表示。如果它仅以 "" 开头,直到终结 ; 的数字提供了某字符的代码的十进值表示。
实体引用(entity reference)引用一个命名实体的内容。对已析普通实体的引用使用 "and" 号(&)和分号(;)作为定界符。参数实体引用则使用百分号(%)和分号(;)作为定界符。
实体引用
[67] Reference ::= EntityRef | CharRef
[68] EntityRef ::= '&' Name ';' [WFC: 声明实体]
[VC: 声明实体]
[WFC: 已析实体]
[WFC: 无递归]
[69] PEReference ::= '%' Name ';' [VC: 声明实体]
[WFC: 无递归]
[WFC: 在 DTD 内]
格式正确性约束: 声明实体 在一个没有任何 DTD 的文件,或一个只有不包含参数实体引用的内部 DTD 子集的文件,或一个 "standalone='yes'" 的文件内,不在外部子集或参数实体内的实体引用中给出的 Name 必须与不在外部子集或参数实体内实体声明中所给出的相匹配,但格式正确的文件不需要声明以下的这些实体:amp,lt,gt,apos 和 quot。普通实体的声明必须先于任何在属性表声明中的缺省值中出现的对它的引用。注意,对于在外部子集或外部参数实体中声明的实体,不进行验证的处理器不必要读取和处理它们的声明;对这些文件,仅当 standalone='yes' 时,实体必须被声明的规则才是一个格式正确性约束。
有效性约束: 声明实体 在一个有外部子集或外部参数实体且 "standalone='no'" 的实体中,实体引用中给出的 Name 必须与实体声明中所给出的相匹配。出于互操作性考虑,有效的文件应该以"4.6 预定义实体"中的简化形式声明实体 amp,lt,gt,apos 和 quot。参数实体的声明必须先于任何对它的引用。类似地,普通实体的声明必须先于任何在属性表声明中的缺省值中出现的对它直接或间接的引用。
格式正确性约束: 已析实体 实体引用不能包含一个未析实体的名字。未析实体只能在声明为 ENTITY 或 ENTITIES 的属性值中引用。
格式正确性约束: 无递归 已析实体不能直接或间接地包含对自身的递归引用。
格式正确性约束: 在 DTD 内 参数实体引用只能在 DTD 中出现。
字符引用和实体引用的例子:
Type less-than (<) to save options. This document was prepared on &docdate; and is classified &security-level;.
参数实体引用的例子:
%ISOLat2;
4.2 实体声明(Entity Declaration)
[定义:实体以如下方式声明:]
实体声明
[70] EntityDecl ::= GEDecl | PEDecl
[71] GEDecl ::= 'S Name S EntityDef S? '>'
[72] PEDecl ::= 'S '%' S Name S PEDef S? '>'
[73] EntityDef ::= EntityValue | (ExternalID NDataDecl?)
[74] PEDef ::= EntityValue | ExternalID
实体引用中的 Name 标识了该实体;对于未析实体,ENTITY 或 ENTITIES 属性的值标识了该实体。如果同一实体被声明了不止一次,绑定第一个遇到的声明。由使用者选择,如果实体被多次声明,XML 处理器可以给出警告。
4.2.1 内部实体(Internal Entities)
[定义:如果实体定义是一个 EntityValue,被定义的实体被称为内部实体。] 内部实体没有单独的物理存储对象,实体的内容在声明中给出。注意常量实体值中一些实体和字符引用的处理可能要求产生正确的置换文本:参见"4.5 内部置换文本的构造"。
内部实体是已析实体。
内部实体声明的例子:
4.2.2 外部实体(External Entities)
[定义:如果实体不是内部的,那么它是一个外部实体,声明如下:]
外部实体声明
[75] ExternalID ::= 'SYSTEM' S SystemLiteral
| 'PUBLIC' S PubidLiteral S SystemLiteral
[76] NDataDecl ::= S 'NDATA' S Name [VC: 声明记法]
如果有 NDataDecl,那么这是一个普通未析实体;否则它是一个已析实体。
有效性约束: 声明记法 Name必须与记法的名字相匹配。
[定义:SystemLiteral 被称为该实体的系统标识符。这是一个 URI 引用(在 [IETF RFC 2396] 中定义,在 [IETF RFC 2732] 中更新),可以由此获得 XML 处理器的输入用于构建此实体的置换文本。] 片断标识符(以 # 开头)出现在系统标识符中是一个错误。如果一个片断标识符作为系统标识符的部分给出,XML 处理器可以给出一个错误。除非在本规范范围之外另外给出(如,一个特殊 DTD 中定义的专用 XML 元素类型,或一个特殊应用规范中定义的处理指令),相对 URI 指相对于实体声明所在资源的位置。因此,一个 URI 可能是相对于文件实体,或相对于包含外部 DTD 子集的实体,或相对于其他一些外部参数实体。
URI 引用需要对某些字符进行编码和转义。不允许出现的字符包括所有非 ASCII 字符,以及 [IETF RFC 2396] 第 2.4 节中列出的不被允许的字符,井号(#)、百分号(%)) 和 [IETF RFC 2732] 中允许的方括号除外。不被允许的字符必须用如下的方法转义:
每个不被允许的字符首先被转换成一个或多个字节的 UTF-8 [IETF RFC 2279] 编码。
任何对应于一个不被允许的字符的八位组用 URI 转义机制转义(即,将其转换成%HH,其中 HH 是字节值的十六进制记法)。
用得到的字符序列置换原来的字符。
除了系统标识符之外,外部标识符还可以包含公共标识符。试图存取实体内容的 XML 处理器可以用公共标识符试着产生一个可选 URI 引用。如果处理器无法做到这一点,它必须使用系统常量中的 URI 引用。在试着匹配之前,公共标识符中所有空白字符串必须被规范为单个空格字符(#x20),同时必须去掉前导和尾随空白。
外部实体声明的例子:
4.3 已析实体(Parsed Entities)
4.3.1 文本声明(Text Declaration)
[定义:每个外部已析实体应该以文本声明作为开始。]
文本声明
[77] TextDecl ::= 'VersionInfo? EncodingDecl S? '?>'
文本声明必须以常量形式给出,而不能使用已析实体的引用。文本声明只能在外部已析实体的开头出现,不允许在其他任何地方出现。在外部已析实体中的文本声明不被认为是其置换文本的一部分
4.3.2 格式正确的已析实体(Well-Formed Parsed Entities)
如果文件实体匹配 document 产生式,那么它是格式正确的。如果外部普通已析实体匹配 extParsedEnt 产生式,那么它是格式正确的。如果外部参数实体匹配 extPE 产生式,那么它是格式正确的。根据定义,外部参数实体是格式正确的。
格式正确的外部已析实体
[78] extParsedEnt ::= TextDecl? content
如果内部普通已析实体的置换文本匹配 content 产生式,那么它是格式正确的。根据定义,所有内部的参数实体都是格式正确的。
实体符合格式正确性的一个结果是 XML 文件的逻辑和物理结构是严格嵌套的;起始标签,结束标签,空元素标签,元素,注释,处理指令,字符引用,或实体引用都不能在一个实体中开始而在另一个实体中结束。
4.3.3 实体中的字符编码(Character Encoding in Entities)
XML 文件中的每个外部已析实体都可以对其字符采用一种不同的编码方案。所有 XML 处理器必须能读取编码为 UTF-8 和 UTF-16 的实体。本规范中的术语 "UTF-8" 和 "UTF-16" 不适用于任何采用其他标识(label)的字符编码,即使这种编码或标识与 UTF-8 或 UTF-16 非常类似。
以 UTF-16 编码的实体必须以 ISO/IEC 10646 增补 F,[ISO/IEC 10646-2000] 增补 H, [Unicode] 的 2.4 节和 [Unicode3] 2.7 节(零宽度不间断空格字符,#xFEFF)中所描述的字节次序标记(Byte Order Mark)开头。这是一个编码签名,即不是 XML 文件中标记的一部分,也不是 XML 文件字符数据的一部分。XML 处理器必须能用此字符区分 UTF-8 编码和 UTF-16 编码的文件。
虽然 XML 处理器只被要求能读取 UTF-8 和 UTF-16 编码的实体,不过对于世界上还有其他的编码方案已有共识。有时可能想让 XML 处理器读取以那些编码方案编码的实体。在没有外部字符编码信息(如 MIME 头)的情况时,以不同于 UTF-8 和 UTF-16 的编码方案存储的实体必须以包含编码声明的文本声明(见 4.3.1 文本声明)开头:
编码声明
[80] EncodingDecl ::= S 'encoding' Eq ('"' EncName '"' | "'" EncName "'" )
[81] EncName ::= [A-Za-z] ([A-Za-z0-9._] | '-')* /* 编码方案的名称只包含拉丁字母 */
在文件实体中,编码声明是 XML 声明的一部分。EncName 是所用编码方案的名称。
在一个编码声明中,值 "UTF-8","UTF-16","ISO-10646-UCS-2" 和 "ISO-10646-UCS-4" 应该用于表示 Unicode 或 ISO/IEC 10646 中的各种不同编码和变换方案,值 "ISO-8859-1","ISO-8859-2",... "ISO-8859-n" (其中 n 是区块号)应该用于表示 ISO 8859 的各个部分,而值 "ISO-2022-JP","Shift_JIS" 和 "EUC-JP" 应该用于表示 JIS X-0208-1997 的各种编码。建议对于在 Internet Assigned Numbers Authority [IANA] 注册的字符编码方案(以字符集(charset)的方式),除了以上所列之外的编码方案,应该用它们的注册名引用。其他的编码应该使用带 "x-" 前缀的名称。欲与之匹配的 XML 处理器应该以大小写敏感的方式对字符编码的名称进行匹配。而且 XML 处理器处理字符编码的名称时,应该将在 IANA 注册的编码名称解释为在 IANA 注册的相应编码,不然就应该当成未知的编码(当然,不要求处理器支持所有在 IANA 注册的编码)。
在缺少外部传输协议(如 HTTP 或 MIME)所提供的信息时,以下情况均是错误:XML 处理器接收到的实体的编码方案与实体所含编码声明中指出的编码方案不同,既不以字节次序标记开头也不以编码声明开头的实体使用了不同于 UTF-8 的编码。注意,因为 ASCII 是 UTF-8 的一个子集,严格说来普通 ASCII 字符不需要编码声明。
TextDecl 出现在外部实体开头以外的地方是一个严重错误。
当 XML 处理器遇到的实体使用了它不能处理的编码时,是一个严重错误。如果一个 XML 实体被确认为使用了某种编码(由默认值,编码声明或高层协议确定),但是它包含了在此编码中非法的八位组序列的话,是一个严重错误。如果一个 XML 实体没有编码声明而它的内容不是合法的 UTF-8 或 UTF-16 编码的话,也是一个严重错误。
包含编码声明的文本声明的例子:
4.4 XML 处理器对实体和引用的处理
下表汇总了字符引用,实体引用,和对未析实体的调用可以出现的上下文,以及每种情况下 XML 处理器的动作。最左边一列的标识指明了识别时的上下文:
内容中的引用
可以在元素的起始标签之后,结束标签之前的任何地方以引用形式出现,对应于非终结符 content。
属性值中的引用
可以在起始标签内的属性值中,或属性声明内的缺省值中以引用形式出现;对应于非终结符 AttValue。
作为属性值
可以以 Name 而不是以引用的形式出现,作为声明为 ENTITY 类型的属性的值,或可以作为声明为 ENTITIES 类型的属性值中的以空白分隔的记号之一。
实体值中的引用
可以在参数中或内部实体的实体声明内的常量实体值中以引用形式出现;对应于非终结符 EntityValue。
DTD 中的引用
在 DTD 的内部或外部子集中的引用,但在 EntityValue,AttValue,PI,Comment,SystemLiteral,PubidLiteral 或被忽略的条件段的内容(见 3.4 条件段)之外。
实体类型 字符
参数 内部普通 外部已析普通 未析
内容中的引用 不被识别 被包含 进行验证时被包含 被禁止 被包含
属性值中的引用 不被识别 作为常量被包含 被禁止 被禁止 被包含
作为属性值 不被识别 被禁止 被禁止 通知 不被识别
实体值中的引用 作为常量被包含 不处理 不处理 被禁止 被包含
DTD 中的引用 作为参数实体被包含 被禁止 被禁止 被禁止 被禁止
4.4.1 不被识别(Not Recognized)
在 DTD 之外,百分号字符 % 没有特殊含义;因此在 DTD 中的参数实体引用在 content 中不被当成标记识别。类似地,除非未析实体的名字出现在已适当声明的属性的值中,否则它们不被识别。
4.4.2 被包含(Included)
[定义:当一个实体的置换文本被当成出现在引用所在位置的文件的一部分一样被存取和处理时,称此实体被包含。] 其置换文本可以包含字符数据和标记(不包括参数实体),其中标记必须以通常的方式识别。(字符串 "AT&T;" 展开为 "AT&T;",尚存的 "and" 号 & 不被识别为实体引用的定界符。)当被表示的字符被当成出现在引用所在位置一样被处理时,称此字符引用被包含。
4.4.3 进行验证时被包含(Included If Validating)
当 XML 处理器识别出一个对已析实体的引用,为了验证该文件,处理器必须包含此实体的置换文本。如果实体是外部的,而处理器不试图验证该 XML 文件,那么处理器可以,但不是必须,包含此实体的置换文本。如果一个不进行验证的处理器不包含此置换文本,它必须通知应用它识别出但没有读取此实体。
这条规则基于这样一个共识:由 SGML 和 XML 的实体机制提供的起初设计用于支持模块化创作的自动包含不一定适合于其他应用,尤其是文件浏览。例如,当浏览器遇到一个外部已析实体引用时,可能选择用可视方式表示其存在但只在被请求时才读取它进行显示。
4.4.4 被禁止(Forbidden)
以下情况被禁止,并构成一个严重错误:
出现对未析实体的引用。
在 DTD 中出现任何字符或普通实体引用,除非它们出现在 EntityValue 或 AttValue 中。
属性值中出现对外部实体的引用。
4.4.5 作为常量被包含(Included in Literal)
当实体引用出现在属性值中或参数实体引用出现在常量实体值中时,它们的置换文本被当成出现在引用所在位置的文件的一部分一样被存取和处理,置换文本中的单双引号总是被当成正常的数据字符而不会结束此常量。例如,下面的例子是格式正确的:
而这个例子不是:
S Name S (ExternalID
| PublicID)
S?
'>'
[VC: 唯一的记法名字]
[83] PublicID ::= 'PUBLIC' S PubidLiteral
有效性约束:唯一的记法名字
一个给定的 Name 只能被一个记法声明所声明.
XML 处理器必须向应用提供任何在属性值中,属性定义中或实体声明中定义或引用的记法的名字和外部标识符。它们还可以将外部标识符解析成系统标识符,文件名,或是应用调用相应处理器处理给定记法格式的数据的所需的其他信息。(但如果 XML 处理器或应用所运行的系统中没有处理 XML 文件声明和引用的记法的相应应用的情况,不是一个错误。)
4.8 文件实体(Document Entity)
[定义:文件实体(document entity)是实体树的根和 XML 处理器的处理起点。] 本规范没有规定 XML 如何定位文件实体;与其他实体不同,文件实体没有名字,而且可以完全不带任何标识地出现在处理器的输入流中。
--------------------next---------------------