翻译|其它|编辑:郝浩|2005-04-01 13:22:00.000|阅读 1696 次
概述:
# 界面/图表报表/文档/IDE等千款热门软控件火热销售中 >>
4. 物理结构
[定义:一个 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]+ ';'
| '&#x' [0-9a-fA-F]+ ';' [WFC: 合法字符]
字符引用和实体引用的例子:
Type <key>less-than</key> (<) to save options. This document was prepared on &docdate; and is classified &security-level;. |
参数实体引用的例子:
<!-- declare the parameter entity "ISOLat2"... --> <!ENTITY % ISOLat2 SYSTEM "http://www.xml.com/iso/isolat2-xml.entities" > <!-- ... now reference it. --> %ISOLat2; |
4.2 实体声明(Entity Declaration)
[定义:实体以如下方式声明:]
实体声明
[70] EntityDecl ::= GEDecl | PEDecl
[71] GEDecl ::= '<!ENTITY' S Name S EntityDef S? '>'
[72] PEDecl ::= '<!ENTITY' 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 内部置换文本的构造"。
<!ENTITY Pub-Status "This is a pre-release of the specification."> |
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),同时必须去掉前导和尾随空白。
外部实体声明的例子:
<!ENTITY open-hatch SYSTEM "http://www.textuality.com/boilerplate/OpenHatch.xml"> <!ENTITY open-hatch PUBLIC "-//Textuality//TEXT Standard open-hatch boilerplate//EN" "http://www.textuality.com/boilerplate/OpenHatch.xml"> <!ENTITY hatch-pic SYSTEM "../grafix/OpenHatch.gif" NDATA gif > |
4.3 已析实体(Parsed Entities)
4.3.1 文本声明(Text Declaration)
[定义:每个外部已析实体应该以文本声明作为开始。]
文本声明
[77] TextDecl ::= '<?xml' 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 编码的话,也是一个严重错误。
包含编码声明的文本声明的例子:
<?xml encoding='UTF-8'?> <?xml encoding='EUC-JP'?> |
4.4 XML 处理器对实体和引用的处理
下表汇总了字符引用,实体引用,和对未析实体的调用可以出现的上下文,以及每种情况下 XML 处理器的动作。最左边一列的标识指明了识别时的上下文:
实体类型 |
字符 | ||||
参数 | 内部普通 | 外部已析普通 | 未析 | ||
内容中的引用 | 不被识别 | 被包含 | 进行验证时被包含 | 被禁止 | 被包含 |
属性值中的引用 | 不被识别 | 作为常量被包含 | 被禁止 | 被禁止 | 被包含 |
作为属性值 | 不被识别 | 被禁止 | 被禁止 | 通知 | 不被识别 |
实体值中的引用 | 作为常量被包含 | 不处理 | 不处理 | 被禁止 | 被包含 |
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)
以下情况被禁止,并构成一个严重错误:
4.4.5 作为常量被包含(Included in Literal)
当实体引用出现在属性值中或参数实体引用出现在常量实体值中时,它们的置换文本被当成出现在引用所在位置的文件的一部分一样被存取和处理,置换文本中的单双引号总是被当成正常的数据字符而不会结束此常量。例如,下面的例子是格式正确的:
<!-- --> <!ENTITY % YN '"Yes"' > <!ENTITY WhatHeSaid "He said %YN;" > |
而这个例子不是:
<!ENTITY EndAttr "27'" > <element attribute='a-&EndAttr;> |
4.4.6 通知(Notify)
当未析实体名字作为记号在声明为 ENTITY 或 ENTITIES
类型的属性的值中出现时,进行验证的处理器必须将此实体和它的相关记法的系统和公共(如果有的话)标识符通知给应用。
4.4.7 不处理(Bypassed)
当实体声明内一个普通实体引用出现在 EntityValue 中时,它不被处理,保持不变。
4.4.8 作为参数实体被包含(Included as PE)
和外部已析实体一样,参数实体只需在进行验证时被包含。当参数实体引用在 DTD
中被识别并被包含时,它的置换文本被前后各加上一个空格字符;其目的在于强制参数实体的置换文本包含整数个 DTD
中的语法记号。这不适用于实体值内的参数实体;对它们的处理见 4.4.5 作为常量被包含
4.5 内部实体置换文本的构建(Construction of Internal Entity)
在讨论内部实体的处理时,区分两种形式的实体值是有帮助的。[定义:常量实体值(literal entity
value)是实际出现在实体声明中用引号扩起的字符串。] 对应于非终结符 EntityValue。置换文本(replacement
text)是置换了字符引用和参数实体引用后的实体内容。
在内部实体声明(EntityValue)中给出的常量实体值可以包括字符引用,参数实体引用和普通实体引用。这些引用必须被整个包含于常量实体值中。如前述方式被包含的实际置换文本必须包含所有被引用的参数实体的置换文本,同时所有被引用的字符必须在常量实体值中字符引用所在位置被包含。但普通实体的引用必须保持不变,不被展开。例如,如果有以下的声明:
<!ENTITY % pub "Éditions Gallimard" > <!ENTITY rights "All rights reserved" > <!ENTITY book "La Peste: Albert Camus, © 1947 %pub;. &rights;" > |
那么实体 "book" 的置换文本为:
La Peste: Albert Camus, ?nbsp;1947 蒬itions Gallimard. &rights; |
一旦引用 "&book;" 出现在文件的内容或属性值中时,普通实体引用 "&rights;" 应该被展开。
这些简单的规则将可能会有复杂的相互作用;参见 "D. 实体和字符引用的展开" 中对一个难的例子的详细讨论。
4.6 预定义实体(Predefined Entities)
[定义:实体和字符引用都可以用于转义左尖括号,"and"
号(&)和其他定界符。普通实体集合(amp,lt,gt,apos,quot)专门用于此目的。也可以使用数值字符引用;一旦被识别,它们立即被展开,同时它们必须被当成字符数据,因此数值字符引用
"<" 和 "&" 可以用于转义出现在字符数据中的 < 和 &。]
不管这些实体是否被声明,所有的 XML 处理器必须能识别它们。出于互操作性考虑,有效的 XML 文件应该如其他实体一样,在使用这些实体前先声明它们。如果实体
lt 或 amp 被声明,它们必须被声明为置换文本为相应被转义字符的字符引用(小于号或 "and"
号)的内部实体;对这些实体需要转义两次以使对它们的引用能得到格式正确的结果。如果实体 gt,apos 或 quot
被声明,它们必须被声明为置换文本为相应被转义的单个字符的内部实体(或指向被转义字符的字符引用;这里转义两次是不必要的,但也是无害的)。例如
<!ENTITY lt "&#60;"> <!ENTITY gt ">"> <!ENTITY amp "&#38;"> <!ENTITY apos "'"> <!ENTITY quot """> |
4.7 记法声明(Notation Declarations)
[定义:记法用名字标识了未析实体的格式,具有记法属性的元素的格式以及处理指令所针对的应用的格式。]
[定义:记法声明赋予记法一个名字用于实体中,属性表声明中和属性值说明中,同时也给出了一个记法的外部标识符使得 XML
处理器或它的客户应用可以定位能以给定记法的格式处理数据的助理应用。]
记法声明
[82] NotationDecl ::= '<!NOTATION' S Name S (ExternalID | PublicID) S?
'>' [VC: 唯一的记法名字]
[83] PublicID ::= 'PUBLIC' S PubidLiteral
有效性约束:唯一的记法名字
一个给定的 Name 只能被一个记法声明所声明.
XML
处理器必须向应用提供任何在属性值中,属性定义中或实体声明中定义或引用的记法的名字和外部标识符。它们还可以将外部标识符解析成系统标识符,文件名,或是应用调用相应处理器处理给定记法格式的数据的所需的其他信息。(但如果
XML 处理器或应用所运行的系统中没有处理 XML 文件声明和引用的记法的相应应用的情况,不是一个错误。)
4.8 文件实体(Document Entity)
[定义:文件实体(document entity)是实体树的根和 XML 处理器的处理起点。] 本规范没有规定 XML
如何定位文件实体;与其他实体不同,文件实体没有名字,而且可以完全不带任何标识地出现在处理器的输入流中。
5. 一致性(Conformance)
5.1 进行验证和不进行验证的处理器(Validating and Non-Validating
Processors)
合乎规范的 XML 处理器可以分为两类:进行验证的和不进行验证的。
进行验证和不进行验证的处理器都必须报告在文件实体的内容中和任何其他它们读到的已析实体中对格式正确性约束的违反。
[定义:进行验证的处理器必须,由使用者选择,报告违反 DTD 声明中所述约束的情况以及不满足本规范中给出的有效性约束的情况。] 要完成这一点,进行验证的 XML
处理器必须读取和处理整个 DTD 和所有在文件中引用的外部已析实体。
不进行验证的处理器只被要求检查文件实体和整个内部 DTD 子集的格式正确性。[定义:虽然它们不被要求检查文件的有效性,但它们必须处理它们读取的所有内部 DTD
子集中的声明和所有参数实体,直到遇到第一个对它们没有读取的参数实体的引用;也就是说,它们必须根据这些声明中的信息规范化属性值,包含内部实体的置换文本,并提供缺省属性值。]
除了 standalone="yes"
的情况,它们在遇到第一个对它们没有读取的参数实体的引用后,不应处理其后的实体声明或属性表声明,因为此实体中包含的声明可能覆盖前面的声明。
5.2 使用 XML 处理器
进行验证的处理器的行为是高度可预测的;它必须读取文件的所有部分,报告所有对格式正确性和有效性的违反。对一个不进行验证的处理器的要求要低一点;它不需要读取文件实体以外的任何文件部分。这对
XML 的处理器的使用者而言可能会有两个重要的影响:
为了使不同 XML 处理器间的互操作有最大的可靠性,使用不进行验证的处理器的应用不应依赖于不要求这些处理器具备的动作。那些要求使用如缺省值或在外部实体中声明内部实体等功能的应用应该使用进行验证的 XML 处理器。
6. 记法(Notation)
本规范中 XML 的形式化文法用一种简单的扩展巴科斯范式(Extended Backus-Naur Form,EBNF)给出。文法中的每一条规则定义了一个符号,形式如下:
symbol ::= expression
如果符号是正则语言的起始符号,则它以大写字母开头,否则以小写字母开头。字符串常量(literal strings)用引号括起。
在规则右边的表达式中,以下表达式用于匹配一个或多个字符的字符串:
"string"
与匹配双引号中所给字符串的常量字符串相匹配。
'string'
与匹配单引号中所给字符串的常量字符串相匹配。
这些符号可以按下列方式组合,以匹配更复杂的模式,其中A和B表示简单表达式:
(expression)
expression 被当成一个单元,可以向本表描述的那样进行组合。
A?
与零个或一个 A 相匹配,即 A 可选。
A B
与 A 后跟 B 的模式相匹配。这个操作符的优先级高于 |,因此 A B | C D 相当于 (A B) | (C D)。
A | B
与 A 或 B 之一相匹配,但不同时匹配。
A - B
与任何匹配 A 但不匹配 B 的字符串相匹配。
A+
与一个或多个 A 相匹配。连接操作的优先级高于 |,因此 A+ | B+ 相当于 (A+) | (B+)。
A*
与零个或多个 A 相匹配。连接操作的优先级高于 |,因此 A* | B* 相当于 (A*) | (B*)。
其他在产生式中使用的记法有:
/* ... */
注释
[ wfc: ... ]
格式正确性约束;用名字标识一个对与某个产生式相关联的格式正确的文件的约束。
[ vc: ... ]
有效性约束;用名字标识一个对与某个产生式相关联的有效的文件的约束。
本站文章除注明转载外,均为本站原创或翻译。欢迎任何形式的转载,但请务必注明出处、不得修改原文相关链接,如果存在内容上的异议请邮件反馈至chenjj@evget.com