当前位置:Linux教程 - Linux - XML1.0 中文文档(第二版)---2. 文件

XML1.0 中文文档(第二版)---2. 文件

本文出自: http://lightning.prohosting.com/~qqiu 译者:裘强 ([email protected])

2. 文件 2.1 格式正确的 XML 文件 2.2 字符 2.3 通用语法成分 2.4 字符数据和标记 2.5 注释 2.6 处理指令 2.7 CDATA 段 2.8 序言和文件类型声明 2.9 独立文件声明 2.10 空白处理 2.11 行尾处理 2.12 语言标识

[定义:如果一个数据对象满足本规范中格式正确的之定义时,它是一个 XML 文件。一个格式正确的 XML 文件可以更进一步是有效的,如果它满足某些进一步的约束的话。]

每一个 XML 文件都有逻辑和物理结构。物理上而言,文件由称为实体的单元组成。一个实体可以引用(refer)其他实体,将它们包含在文件中。文件开始于""根(root)""或文件实体。逻辑上而言,文件由声明,元素,注释,字符引用和处理指令组成,所有这些都在文件中用显式标记指明。逻辑和物理结构必须如""4.3.2 格式正确的已析实体""中所描述的那样严格地嵌套。
2.1 格式正确的 XML 文件(Well-Formed XML Documents)

[定义:一个文本对象是一个格式正确的 XML 文件如果它满足:]

1. 作为一个整体,它匹配 document 产生式。
2. 它满足本规范中定义的所有格式正确性约束。
3. 此文件中直接或间接引用的每一个已析实体都是格式正确的。

文件
[1] document ::= prolog element Misc*

匹配 document 产生式意味着:

1. 它包含一个或多个元素。
2. [定义:有且仅有一个称为根(root)或文件元素的元素,它不出现在其他任何元素的内容(content)中。] 对于其他所有元素,如果起始标签在另一个元素的内容中,则其结束标签也在同一元素的内容中。换一个更简单的说法,以起始标签和结束标签为界的各个元素,必须严格地嵌套。

[定义:这样做的结果是,对于每一个非根的元素 C,文件中另有一个元素 P,C 在 P 的内容中,而不在其他任何被 P 所包含的元素的内容中。P 被称为 C 的父元素(parent),而 C 被称为 P 的子元素(child)。]
2.2 字符

[定义:一个已析实体包含文本(text),文本是一个字符(character)序列,可以表示标记或字符数据。] [定义:一个字符是 ISO/IEC 10646 [ISO/IEC 10646](或 [ISO/IEC 10646-2000])中定义的文本最小单元。合法的字符包括制表符,回车,换行以及 Unicode 和 ISO/IEC 10646 中定义的合法字符。在制定本文档时,在附录 A.1 正式参考文献中引用的标准都是当时的最新版本,在这些标准的增补版或新版中可能会加入新的字符。因此,XML 处理器必须能接受产生式 Char 中所定义范围内的任意字符。不提倡使用 [Unicode] 6.8 节(或 [Unicode3] 3.6 节 D21 )中定义的""兼容字符(compatibility characters)""。]
字符范围
[2] Char ::= #x9 | #xA | #xD | [#x20-#xD7FF] | [#xE000-#xFFFD] | [#x10000-#x10FFFF] /* 除了代用块(surrogate block),FFFE 和 FFFF 以外的任意 Unicode 字符。*/

将字符代码编码成位模式的机制各个实体间可能会有所不同。所有的 XML 处理器必须接受 10646 中的 UTF-8 和 UTF-16 编码;用于指出所用编码或指定使用其他编码的机制在后面的""4.3.3 实体中的字符编码""中讨论。
2.3 通用语法成分

本节中定义了一些在文法中广泛使用的符号。

S(空白)包括一个或多个空格字符(#x20),回车,换行和制表符。
空白
[3] S ::= (#x20 | #x9 | #xD | #xA)+

为方便起见,字符被分为字母,数字和其他字符三类。字母可以是字母表中的字母,或是一个音节基字符(syllabic base character),也可以是一个表意字符。在""B. 字符的分类""中给出了每一类字符的完整定义。

[定义:名字(name)是以字母或某些标点符号开头的记号,后跟字母,数字,连字符,下划线,冒号或句号,这些符号统称为命名字符(name character)。] 以 ""xml"" 或其他任何匹配 ((''X''|''x'') (''M''|''m'') (''L''|''l'')) 的字符串开头的名字,被保留用于本规范的此版本或后续版本的标准化。

注:

建议 XML 中的名字空间 [XML Names] 中赋予了包含冒号的名字某种含义。因此除非用于名字空间,XML 文件作者不应该在 XML 名字中使用冒号,但 XML 处理器应该接受冒号作为一个命名字符。

Nmtoken(名字记号,name token)是任何命名字符的混合体。
名字和记号
[4] NameChar ::= Letter | Digit | ''.'' | ''-'' | ''_'' | '':'' | CombiningChar | Extender
[5] Name ::= (Letter | ''_'' | '':'') (NameChar)*
[6] Names ::= Name (S Name)*
[7] Nmtoken ::= (NameChar)+
[8] Nmtokens ::= Nmtoken (S Nmtoken)*

常量数据是任何用引号括起的字符串,不包括用作定界符的引号。常量用于指明内部实体的内容(EntityValue),属性值(AttValue),以及外部标识符(SystemLiteral)。注意,对 SystemLiteral 的语法分析可以不扫描标记。
常量
[9] EntityValue ::= ''""'' ([^%&""] | PEReference | Reference)* ''""''
| ""''"" ([^%&''] | PEReference | Reference)* ""''""
[10] AttValue ::= ''""'' ([^<&""] | Reference)* ''""''
| ""''"" ([^<&''] | Reference)* ""''""
[11] SystemLiteral ::= (''""'' [^""]* ''""'') | (""''"" [^'']* ""''"")
[12] PubidLiteral ::= ''""'' PubidChar* ''""'' | ""''"" (PubidChar - ""''"")* ""''""
[13] PubidChar ::= #x20 | #xD | #xA | [a-zA-Z0-9] | [-''()+,./:=?;!*#@$_%]

注:

虽然产生式 EntityValue 允许定义只包含单个 < 的实体(如,),但是强烈建议避免这种用法,因为对此实体的任何引用都会引起一个格式正确性错误。
2.4 字符数据和标记

文本由字符数据和标记混合构成。[定义:标记包括起始标签,结束标签,空元素标签,实体引用,字符引用,注释,CDATA 段定界符,文件类型声明,处理指令,XML 声明,文本声明,以及任何在文件实体顶层的空白(即,在文件元素之外且不在任何其他的标记中)。]

[定义:其他所有非标记的文本组成文件的字符数据。]

""and""号(&)和左尖括号(<)只有作为标记定界符,或在注释,处理指令,或 CDATA 段中时才能以常量形式出现。如果在其他地方需要用到这两个字符,它们必须用数值式字符引用来转义或分别用字符串""&""和""<""表示。右尖括号(>)可以用"">""表示,而当它在内容中的字符串""]]>""中出现,但此字符串不表示一个 CDATA 段的结束时,出于兼容性考虑,必须用"">""或一个字符引用转义得到。

在一个元素的内容中,字符数据可以是不包括任何标记的起始定界符的任意字符串。在一个 CDATA 段中,字符数据可以是不包括 CDATA 段结束定界符""]]>""的任意字符串。

为了允许在属性值中包含单引号和双引号,省略符或称单引号('')可以被表示为""''"",而双引号("")可以被表示为""""""。
字符数据
[14] CharData ::= [^<&]* - ([^<&]* '']]>'' [^<&]*)
2.5 注释

[定义:注释可以在其他标记之外的文件中的任何位置出现。另外,它们可以在文件类型声明中文法允许的地方出现。它们不是文件字符数据的一部分,XML 处理器可以,但不是必须,允许一个应用检索注释的文本。出于兼容性考虑,字符串""--""(双连字符)不能在注释中出现。] 注释中的参数实体不被识别。
注释
[15] Comment ::= ''''

注释的一个例子:

注意,此文法不允许注释以 ---> 结尾。下面的例子不是格式正确的。

2.6 处理指令

[定义:处理指令(PI)允许文件中包含由应用来处理的指令。]
处理指令
[16] PI ::= ''PITarget (S (Char* - (Char* ''?>'' Char*)))? ''?>''
[17] PITarget ::= Name - ((''X'' | ''x'') (''M'' | ''m'') (''L'' | ''l''))

PI 不是文件字符数据的一部分,但必须传递给应用。PI 以用于指示传递给哪个应用的目标(PITarget)开头。目标名字 ""XML"",""xml"",等等,保留用于本规范的此版本或后续版本的标准化。XML 记法机制可以用于 PI 目标的形式化声明。参数实体在处理指令中不被识别。
2.7 CDATA 段

[定义:CDATA 段可以出现在字符数据可以出现的任何地方,它们用于转义包含会被识别为标记的字符串的文本块。CDATA 段以字符串 """" 结束:]
CDATA 段
[18] CDSect ::= CDStart CData CDEnd
[19] CDStart ::= '' CData ::= (Char* - (Char* '']]>'' Char*))
[21] CDEnd ::= '']]>''

在一个 CDATA 段内,只有 CDEnd 字符串被识别为标记,因此左尖括号和""&""可以以它们的常量形式出现,不需要(也不能)被换码为""<""和""&""。CDATA 段不能嵌套。

一个 CDATA 段的例子,其中""""和""""被识别为字符数据,而不是标记:
2.8 序言(prolog)和文件类型声明

[定义:XML 文件应该以一个 XML 声明开始,其中指明了所用 XML 的版本。] 例如,以下是一个完整的 XML 文件,它是格式正确的,但不是有效的:
Hello, world!

下面这个也同样:
Hello, world!

版本号 ""1.0"" 应该用于表明与本规范的本版本相一致,如果使用了值 ""1.0"" 但又与本规范的本版本不一致,那么这是文件的一个错误。XML 工作组打算赋予本规范的后续版本不同于 ""1.0"" 的数值,但这并不代表开发后续版本的承诺,也不代表如果有后续版本,会使用任何特殊的命名方案的承诺。因为不排除有后续版本的可能性,提供了本构造(construct)作为一旦需要时进行自动版本识别的手段。当处理器收到的文件标有它们不支持的版本时,可以给出一个错误。

XML 文件中标记的功能是描述文件的存储格式和逻辑结构,并将属性-值对和逻辑结构关联起来。XML 提供一种称为文件类型声明的机制,用于定义对逻辑结构的约束,支持预定义存储单元的使用。[定义:如果一个 XML 文件有相应的文件类型声明并且它遵循其中的约束,则称它是有效的(valid)。]

文件类型声明必须位于文件第一个元素之前。
序言
[22] prolog ::= XMLDecl? Misc* (doctypedecl Misc*)?
[23] XMLDecl ::= ''VersionInfo EncodingDecl? SDDecl? S? ''?>''
[24] VersionInfo ::= S ''version'' Eq (""''"" VersionNum ""''"" | ''""'' VersionNum ''""'')/* */
[25] Eq ::= S? ''='' S?
[26] VersionNum ::= ([a-zA-Z0-9_.:] | ''-'')+
[27] Misc ::= Comment | PI | S

[定义:XML 文件类型声明包含或指向标记声明,标记声明提供某一类文件的文法。这种文法被称为文件类型定义(document type difinition,DTD)。文件类型定义可以指向一个外部子集(一种特殊类型的外部实体),或者可以在一个内部子集中直接包含标记声明,或者两者兼用。一个文件的文件类型定义由这两个子集合在一起组成。]

[定义:标记声明可以是元素类型声明,属性表声明,实体声明,或是记法声明。] 这些声明可以如下面格式正确性和有效性约束中所述,全部或部分地包含在参数实体中,""4. 物理结构""中有更多的信息。
文件类型定义
[28] doctypedecl ::= ''S Name (S ExternalID)? S? (''['' (markupdecl | DeclSep)* '']'' S?)? ''>'' [VC: 根元素类型]
[WFC: 外部子集]
/* */
[28a] DeclSep ::= PEReference | S [WFC: 声明间的参数实体]
/* */
[29] markupdecl ::= elementdecl | AttlistDecl | EntityDecl | NotationDecl | PI | Comment [VC: 严格的声明/参数实体嵌套]
[WFC: 内部子集中的参数实体]

注意,要构建包含了一个既不指向外部子集也不包含内部子集的 doctypedecl 而格式正确的文件是可能的。

标记声明可以全部或部分地由参数实体的置换文本组成。本规范后面的各个非终结符(elementdecl,AttlistDecl,等等)产生式描述的是在所有的参数实体被包含(include)之后的声明。

除了在常量,处理指令,注释和被忽略的条件段的内容中出现的参数实体引用以外,DTD 中的其他任何地方(内部或外部子集以及外部参数实体)的参数实体引用都被识别(见 3.4 条件段)。在实体值常量中的参数实体引用也被识别。内部子集中参数实体引用的使用限制如下所述。

有效性约束: 根元素类型(Root Element Type) 文件类型声明中的 Name 必须匹配根元素的类型。

有效性约束: 严格的声明/参数实体嵌套 参数实体的置换文本必须用标记声明严格嵌套。即,如果一个标记声明(上面的 markupdecl)的第一个或最后一个字符被包含于一个参数实体引用的置换文本中,两者必须都在此置换文本中。

格式正确性约束: 内部子集中的参数实体

在内部 DTD 子集中,参数实体引用只能出现在标记声明可以出现的地方,而不能在标记声明内部出现。(这个约束不适用于出现在外部参数实体内的引用,也不适用于外部子集。)

格式正确性约束: 外部子集

外部子集(如果有的话)必须匹配产生式 extSubset。

格式正确性约束: 声明间的参数实体

一个 extSubsetDecl。

同内部子集一样,外部子集和任何 DeclSep 中引用的外部参数实体,必须由一系列被非终结符 markupdecl 所允许的完整的标记声明组成,其中可以夹杂空白字符或参数实体引用。但是,外部子集和外部参数实体的部分内容可以通过使用条件段(conditional section)被有条件地忽略,在内部子集中则不允许这么做。
外部子集
[30] extSubset ::= TextDecl? extSubsetDecl
[31] extSubsetDecl ::= ( markupdecl | conditionalSect | DeclSep)* /* */

外部子集和外部参数实体与内部实体不同之处还在于:在它们内,参数实体引用不仅可以出现在标记声明间,还可以出现在标记声明内。

有文件类型声明的 XML 文件的例子:
Hello, world!

系统标识符 ""hello.dtd"" 给出了此文件的 DTD 的地址(一个 URI 引用)。

声明也可以如同下面这个例子一样直接(locally)给出:
]> Hello, world!

如果同时使用外部和内部子集,子集子集被看成出现在外部子集之前,这意味着内部子集中的实体和属性表声明的优先级要比在外部子集中的高。
2.9 独立文件声明

当文件从 XML 处理器递给应用时,标记声明可以影响它的内容,属性缺省值和实体声明是其中的例子。可以作为 XML 声明一个成分的独立文件声明,指明了是否存在着在文件实体外或在参数实体中的声明。[定义:外部标记声明被定义为出现在外部子集或参数实体(外部或内部,包括内部参数实体是因为并不强制不进行验证的处理器读取其中的标记声明)中的标记声明。]
独立文件声明
[32] SDDecl ::= S ''standalone'' Eq ((""''"" (''yes'' | ''no'') ""''"") | (''""'' (''yes'' | ''no'') ''""'')) [VC: 独立文件声明]

在一个独立文件声明中,值 ""yes"" 表示对于文件实体没有外部标记声明(不论是在 DTD 外部子集中,还是在由内部实体引用的外部参数实体中)会影响从 XML 处理器传递给应用的信息。值 ""no"" 表示有或可能有这样的外部标记声明。注意,独立文件声明只是表示外部声明的存在,如果文件中存在对外部实体的引用,而这些实体已在内部声明时,不影响它的独立状态。

如果不存在外部标记声明,独立文件声明没有意义。如果存在外部标记声明,但没有独立文件声明,就假定取值 ""no""。

某些网络传输应用也许需要独立的文件,任何满足 standalone=""no"" 的 XML 文件可以通过一定的算法转换为独立文件。

有效性约束: 独立文件声明 独立文件声明必须取值为 ""no"",如果任何外部标记声明中包含:

* 有缺省值的属性的声明,如果适用这些属性的元素出现在文件中而又没有给这些属性赋值的话。
* (除了 amp,lt,gt,apos,quot 外的)实体的声明,而对这些实体的引用出现在文件中的话。
* 其值需要规范化的属性的声明,如果这些出现在文件中的属性的值会因规范化而改变的话。
* 具有元素型内容的元素类型的声明,如果在这些类型的任一实例中直接出现空白的话。

具有独立文件声明的 XML 声明的例子:
2.10 空白处理

在编辑 XML 文件时,使用""空白""(空格,制表符,空行)来分开标记以获得更好的可读性是很方便的。通常在文件的交付版本中不想包含这些空白。另一方面,必须保留在交付版本中的有意义的空白是很常见的,如在诗歌和源码中的空白。

XML 处理器必须始终把不是标记的所有字符传递给应用。一个进行验证的 XML 处理器必须同时通知应用这些字符中的那一些组成了出现在元素型内容中的空白。

可以在元素中附加一个名为 xml:space 的特殊属性,以通知应用应该保留此元素中的空白。在有效的文件中,此属性和其他属性一样,使用时必须声明。它必须被声明为枚举类型,可以取值 ""default"" 和 ""preserve"" 两者之一,也可以两个都取。例如:




""default"" 表示可以对此元素使用应用的缺省空白处理模式,""preserve"" 表示应用应该保留所有的空白。这适用于其所处元素的内容中的所有元素,除非被另一个 xml:space 属性的实例所覆盖。

任何文件的根元素被认为对应用的空白处理方式不作要求,除非它给此属性赋了值或将此属性声明为带缺省值。
2.11 行尾处理

为编辑的方便起见,存储 XML 已析实体的计算机文件经常用行来组织。通常这些行用回车符(#xD)和换行符(#xA)的一些组合来分隔。
为了使应用的工作简单化,XML 处理器应在将字符传给应用前,将外部已析实体(包括文件实体)中的两字符序列 ""#xD#xA"" 或没有尾随 #xA 的 #xD 在进行语法分析前转换成单个 #xA 字符。
2.12 语言标识

在进行文件处理时,标识出其内容所使用的自然或形式化语言经常是很有用的。可以在文件中插入一个名为 xml:lang 的特殊属性用于指出 XML 文件中任何元素的内容和属性所使用的语言。在有效的文件中,此属性和其他属性一样,使用时必须声明。此属性的值是 [IETF RFC 1766],Tags for the Identification of Languages 或其后的 ITEF 标准中定义的语言标识符。

注:

[IETF RFC 1766] 中的标签由 [ISO 639] 中定义的两字母语言码和 [ISO 3166] 中定义的两字母国家码构成,或者由 Internet Assigned Numbers Authority [IANA-LANGCODES] 注册的语言标识符构成。 预计 [IETF RFC 1766] 的后继标准将会引入三字母语言码用于表示 [ISO 639] 中没有涉及的语言。

(产生式 33 到 38 已被删除。)

举例如下:
内的参数实体引觲idth=""100%"" bgcolor=""#80FFFF"">

The quick brown fox jumps over the lazy dog.

What colour is it?

What color is it?
Habe nun, ach! Philosophie, Juristerei, und Medizin und leider auch Theologie durchaus studiert mit hei遝m Bem黨''n.

xml:lang 所表示的语言选择适用于它所处元素的所有属性和内容,除非被此内容中的元素内的另一个 xml:lang 的实例所覆盖。

xml:lang 的一个简单声明可以采用如下形式:
xml:lang NMTOKEN #IMPLIED

但是如果合适的话,也可以给出特定的缺省值。在一本供英国学生使用的法文诗歌集中,评注和注解使用英语,xml:lang 属性可以这样声明: