当某元素类型可以包含字符数据,其间可以随意穿插子元素时,称此元素类型具有混合型内容。在这种情况下,对子元素的类型可能有所限制,但对它们的次序和出现次数没有限制:
混合型内容声明
[51] Mixed ::= '(' S? '#PCDATA' (S? '|' S? Name)* S? ')*' | '(' S? '#PCDATA' S? ')' [ VC:严格的组/PE嵌套 ] [ VC:无重复类型 ]
其中Name给出了子元素的元素的类型。 有效性约束:无重复类型
同一名字在单个混合型内容声明中只能出现一次。 混合内容声明的例子:
3.3 属性表声明
属性用于关联名字-值对和元素。属性值说明只能在起始标签和空元素标签中出现; 因此,用于识别它们的产生式出现在\起始标签,结束标签和空元素标签\中。属性表声明可以用于:
定义与一给定元素类型有关的属性集。 确定这些属性的类型限制。 提供属性的缺省值。
属性表声明 详细说明了与给定元素类型相关联的每一个属性的名字,数据类型和缺省值(如果有的话): 属性表声明
[52] AttlistDecl ::= '' [53] AttDef ::= S Name S AttType S DefaultDecl
AttlistDecl规则中Name是元素的类型。由用户选择,当属性声明相关的元素类型没有被声明时,XML处理器可以给出一个警告,但这不是一个错误。AttDef规则中的Name是属性的名字。
当 与某个给定元素类型相关的AttlistDecl超过一个时,这些声明中的内容被合并在一起。当给定元素类型的某个属性的定义超过一个时,绑定第一个定 义,其余定义被忽略。出于互操作性考虑,DTD的作者可以选择一个给定的元素类型至多有一个属性表声明,一个给定的属性名至多有一个属性定义,以及每个属 性表声明至少有一个属性定义。出于互操作性考虑,当一个给定元素有超过一个的属性表声明或一个给定属性有超过一个的属性定义时,XML处理器可以,由用户 选择,给出警告,但这不是一个错误。
3.3.1 属性类型
XML属性有三种类型:字符串类型,一组记号化类型和枚举类型。字符串类型可以以任意常量字符串为值; 各个记号化类型有不同的词法和语义约束,如下:
属性类型
[54] AttType ::= StringType | TokenizedType | EnumeratedType
[55] StringType ::= 'CDATA'
[56] TokenizedType ::= 'ID' [ VC:ID ] [ VC:每种元素类型一个ID ] [ VC:ID属性的缺省值 ] | 'IDREF' [ VC:IDREF ] | 'IDREFS' [ VC:IDREF ] | 'ENTITY' [ VC:实体名 ] | 'ENTITIES' [ VC:实体名 ] | 'NMTOKEN' [ VC:名字记号 ] | 'NMTOKENS' [ VC:名字记号 ] 有效性约束:ID
ID类型的值必须匹配Name产生式。作为此类型值的名字只能在XML文件中出现一次;即,ID类型的值必须能唯一标识元素。
有效性约束:每种属性类型一个ID 每种属性类型只能有一个ID属性。 有效性约束:ID属性的缺省值
ID属性必须有一个声明为#IMPLIED或#REQUIRED的缺省值。 有效性约束:IDREF
IDREF类型的值必须匹配Name产生式,IDREFS类型的值必须匹配Names产生式;每一个Name必须匹配XML文件中某些元素ID属性的值;也就是说,IDREF类型的值必须匹配某些ID属性的值。
有效性约束:实体名
ENTITY类型的值必须匹配Name产生式,ENTITIES类型的值必须匹配Names产生式;每一个Name必须匹配DTD中声明的未析实体的名字。
有效性约束:名字记号
NMTOKEN类型的值必须匹配Nmtoken产生式;NMTOKENS类型的值必须匹配Nmtokens产生式。 枚举类型的属性可以在声明中提供的取值表中取值。有两种枚举类型: 枚举属性类型
[57] EnumeratedType ::= NotationType | Enumeration
[58] NotationType ::= 'NOTATION' S '(' S? Name (S? '|' S? Name)* S? ')' [ VC:记法属性 ] [59] Enumeration ::= '(' S? Nmtoken (S? '|' S? Nmtoken)* S? ')' [ VC:枚举 ]
一个NOTATION类型的属性标识了一种用于解释与此属性相关的元素的记法,此记法中用系统或公共标识符在DTD中声明。
有效性约束:记法属性
此类型的值必须与声明中所包含的记法名之一相匹配;声明中的所有记法名都必须声明。 有效性约束:枚举
此类型的值必须与声明中所包含的Nmtoken记号之一相匹配。
出于互操作性考虑,同一Nmtoken只能在单个元素类型的枚举属性类型中出现一次。 3.3.2 属性缺省值
属性声明提供的信息指明了某属性是否必须出现,同时指明了在被声明的属性不是必须出现而文件中没有出现此属性的情况下,XML处理器应如何处理。
属性缺省值
[60] DefaultDecl ::= '#REQUIRED' | '#IMPLIED' | (('#FIXED' S)? AttValue) [ VC:必须的属性 ] [ VC:合法的属性缺省值 ] [ WFC:在属性值中无< ] [ VC:固定的属性缺省值 ]
在 一个属性声明中,#REQUIRED表示必须总是提供此属性,#IMPLIED表示不提供缺省值。如果声明既不是#REQUIRED,也不 是#IMPLIED,那么AttValue值包含了所声明的缺省值;关键字#FIXED规定此属性必须总是有缺省值。如果声明了一个缺省值,当XML处理 器遇到一个被省略的属性时,它将当成此属性以缺省值出现
有效性约束:必须的属性
如果缺省值声明是关键字#REQUIRED,那么属性表声明所指类型的元素中都必须有此属性。 有效性约束:合法的属性缺省值
被声明的属性缺省值必须满足被声明的属性类型的词法约束。 有效性约束:固定的属性缺省值
如果某属性的缺省值用关键字#FIXED声明,此属性的所有实例必须匹配该缺省值。 属性表声明的例子:
id ID #REQUIRED name CDATA #IMPLIED>
type (bullets|ordered|glossary) \
method CDATA #FIXED \
3.3.3 属性-值对的规范化(Attribute-Value Normalization)
在将属性的值传给应用或检验有效性之前,XML处理器必须将其规范化: 对字符引用的处理是将被引用的字符附加在属性值之后
对实体引用的处理是递归地处理实体的置换文本
对空白字符(#x20,#xD,#xA,#x9)的处理是将#x20附加于规范化的值之后,例外是对作为内部已析实体或内部已析实体常量实体值一部分的\只附加一个#x20。
对于其他字符的处理是将它们附加于规范化的值之后
如果被声明的值不是CDATA,那么XML处理器必须继续处理规范化后的值,去掉其前导和尾随空格(#x20)字符,并将空格(#x20)字符序列替换成单个空格(#x20)字符。
不进行验证的语法分析器应该将所有尚未读到声明部分的属性当成被声明为CDATA。 3.4 条件段(Conditional Sections)
条件段是文件类型声明外部子集的一部分,取决于相应的关键字,它们或被包含在DTD逻辑结构之内,或被排除在DTD逻辑结构之外。
条件段
[61] conditionalSect ::= includeSect | ignoreSect
[62] includeSect ::= '' [63] ignoreSect ::= '' [64] ignoreSectContents ::= Ignore ('' Ignore)* [65] Ignore ::= Char* - (Char* ('') Char*)
同内部或外部DTD子集一样,条件段可以包含一个或多个完整的声明,注释,处理指令,或嵌套的条件段,其间可以夹杂空白。
如果条件段的关键字是INCLUDE,那么条件段的内容是DTD的一部分,如果条件段的关键字是IGNORE,那么条件段的内容逻辑上不是DTD的一部分。 注意对于可靠的语法分析过程,甚至必须读取被忽略的条件段的内容以检测嵌套的条件段,保证最外层(被忽略)的条件段的结尾被恰当地检测到。如果一个关键字 为INCLUDE的条件段出现在更大的关键字为IGNORE的条件段中,内外两个条件段都被忽略。
如果条件段的关键字是一个参数实体引用,处理器在决定是否包含或忽略此条件段前,必须先将该参数实体置换成其内容。
一个例子:
}>
}>
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]+ ';' | '' [0-9a-fA-F]+ ';' [ WFC:合法字符 ] 规范性约束:合法字符
用字符引用引用的字符必须匹配Char产生式。
如果字符引用以\开头,直到终结;的数字和字母提供了某字符在ISO/IEC 10646中代码的一个十六进制表示。如果它仅以\开头,直到终结;的数字提供了某字符的代码的十进值表示。
实体引用(entity reference)引用一个命名实体的内容。对已析普通实体的引用使用\号(&)和分号(;)作为定界符。参数实体引用则使用百分号(%)和分号(;)作为定界符。
实体引用
[67] Reference ::= EntityRef | CharRef
[68] EntityRef ::= '&' Name ';' [ WFC:声明实体 ] [ VC:声明实体 ] [ WFC:已析实体 ] [ WFC:无递归 ]
[69] PEReference ::= '%' Name ';' [ VC:声明实体 ] [ WFC:无递归 ] [ WFC:在DTD内 ] 规范性约束:声明实体