XML Schema. 22
全局/局部声明/定义... 23
模式与名称空间... 23
目标名称空间... 23
局部元素和属性的限定... 24
未声明目标名称空间... 26
在XML实例文档中引用Schema模式文档... 26
注解... 27
简单类型... 28
内置简单类型... 29
自定义简单类型... 29
限制范围... 30
限制长度... 30
指定精度... 31
枚举值... 31
模式匹配... 31
空白处理... 32
fixed属性... 32
列表类型... 33
自定义列表类型... 33
限定列表类型... 33
联合类型... 35
自定义联合类型... 35
限制联合类型... 36
阻止简单类型派生... 37
复杂类型... 37
从简单内置类型派生复杂类型... 38
xs:attribute元素的use、default和fixed属性... 38
anyType. 39
纯元素内容... 39
xs:sequence. 39
xs:choice. 40
xs:all42
元素的出现次数限制... 43
元素的默认值与固定值... 45
空元素... 45
混合内容... 46
元素组... 46
属性组... 47
元素通配符xs:any. 48
属性通配符xs:anyAttribute. 50
派生复杂类型... 51
扩展派生复杂类型... 52
扩展简单内容... 52
扩展纯元素内容... 53
扩展混合内容... 55
扩展空内容... 56
限制派生复杂类型... 56
限制简单内容... 56
限制纯元素内容... 57
限制混合内容... 58
限制空内容... 60
在实例文档中使用派生类型... 60
替换组... 62
抽象元素和类型... 63
控制派生类型的创建和使用... 64
一致性约束... 66
unique约束... 66
key约束... 68
keyref约束... 68
引入其他模式文档... 69
包含xs:include. 69
重定义xs:redefine. 70
导入xs:import71
XML Schema
模式指的是依照XML Schema规范,使用http://www.w3.org/2001/XMLSchema名称空间中的元素来描述XML文档结构的规则集。每个模式定义都是以一个根元素 xs:schema 开始,该元素属于 http://www.w3.org/2001/XMLSchema 名称空间。
模式用于定义XML文档结构,对XML进行约束,符合某个模式的XML文档称为实例。
声明是指括元素、属性的声明。
定义是指数据类型、元素组、属性组和一致性约束的定义。
不只是属性值有类型,元素也是有类型的。
元素如果包含子元素或者带有属性则称为复杂类型;如果元素仅仅包含字符数据,而不包含任何子元素,也不带有属性则为简单类型。属性总是只具有简单类型,因为属性不能有子元素或其他属性。
全局/局部声明/定义
直接在 xs:shema 元素下声明的元素、属性,它们可以通过xs:element和xs:attribute元素的ref属性来引用。
在全局声明中不能使用ref属性。全局声明的元素在实例文档中可以作为根元素出现。
另外,类型也可以定义成全局的。
模式与名称空间
目标名称空间
目标名称空间使用xs:schema元素的targetNamespace属性来指定:
targetNamespace="http://www.sunxin.org/book" 2 xmlns:book="http://www.sunxin.org/book"> 3
1、 所有在Schema模式文档里出现的用来定义模式规则的元素及内置类型都属性http://www.w3.org/2001/XMLSchema名称空间中元素。
2、 使用targetNamespace属性指定文档名称空间为http://www.sunxin.org/book,即表示在该模式文档中声明的元素、定义的类型都属于都属性于这个目标空间了。
3、 声明名称空间http://www.sunxin.org/book,并为该名称空间绑定前缀book,使用该前缀来引用http://www.sunxin.org/book名称空间中的类型bookType。
4、 文档中定义的类型都属于文档名称空间,因此在引用类型时,需要加上book前缀。
5、 在定义类型时,如果指定类型名,则不需要加上任何前缀,当使用targetNamespace属性后,在模式文档中定义的任何类型都属于目标名称空间。
带有xs前缀的元素和类型属于http://www.w3.org/2001/XMLSchema名称空间,而其他元素和类型则属于目标名称空间。注意,只有模式文档中的全局元素和全局属性才属于目标名称空间。上面的例子中,全局元素book属于目标名称空间,而局部元素title和author则不属于目标名称空间。
与上面模式对应的实例文档如下:
局部元素和属性的限定
在上面例子中,局部元素title和author没有被文档名称空间所限定,即不属于任何名称空间,如果要限定,可以通过 xs:schema 元素的elementFormDefault和attibuteFormDefault属性来设置。
限定局部元素:
xmlns="http://www.sunxin.org/book" targetNamespace="http://www.sunxin.org/book" elementFormDefault="qualified">
elementFormDefault的默认值为“unqualified”,即对局部声明的元素不加限定。符合上面模式的实例文档如下:
如果属性被声明为全局属性或者xs:schema元素的attibuteFormDefault属性被设置成“qualified”的话,那么属性就必须在实例文档中将以带名称空间前缀方式出现。实际上,需要限定的属性必须明确加上名称空间前缀,因为XML名称空间推荐标准中并没有给出关于属性默认名称空间的机制,一个没有前缀的属性将不在任何的名称空间中。属性是附属于元素的,对于属性添加名称空间不是很有必要,因此在多数应用中都没有给属性添加限定。
下面是使用了attibuteFormDefault属性的模式文档:
xmlns="http://www.sunxin.org/book" targetNamespace="http://www.sunxin.org/book" elementFormDefault="qualified" attributeFormDefault="qualified">
attibuteFormDefault的默认属性值也是“unqualified”,符合上面的XML文档:
elementFormDefault和attibuteFormDefault属性除了在xs:schema 元素中设置外,还可以在xs:element和xs:attribute元素上分别使用form属性来限制局部元素与属性,不过这只能设置了元素或属性都起限定作用:
xmlns="http://www.sunxin.org/book" targetNamespace="http://www.sunxin.org/book">
未声明目标名称空间
上面的bookType类型和声明的book元素都是没有名称空间限定的,所以在模式文档中引用类型或元素时,不需要添加任何的名称空间前缀。
如果对XMLSchema的元素和类型使用默认名称空间,那么对XMLSchema类型的引用也许不能和对用户自定义类型的引用相区分,从而导致模式文档错误:
报错:'bookType' must refer to an existing simple or complex type.
这是因为验证器认为对bookType类型的引用是默认名称空间(http://www.w3.org/2001/XMLSchema)中定义的类型,而该名称空间中并没有这种类型,所以就报错了。
在XML实例文档中引用Schema模式文档
两个用于引用Schema模式文档的特殊属性:xsi:schemaLocation、xsi:noNamespaceSchemaLocation,前者用于声明了目标名称空间的模式文档,后者用于没有文档名称空间模式的文档,它们通常在实例文档中使用。
l xsi:schemaLocation
xsi:schemaLocation属性值由一对URI组成,使用空白符分开。第一个URI是名称空间的名字,即模式中的目标名称空间,第二个URI给出模式文档的位置,模式处理器将从这个位置读取模式文档。
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 1 xsi:schemaLocation="http://www.sunxin.org/book book.xsd"> 2
1、 声明XMLSchema实例名称空间(http://www.w3.org/2001/XMLSchema-instance),前缀一般为xsi,这样模式处理器就可以识别xsi:schemaLocation属性。
2、 使用xsi:schemaLocation属性指定名称空间http://www.sunxin.org/book和模式位置为book7.xsd相关。这里的book.xsd中声明的目标名称空间要求是http://www.sunxin.org/book。
xsi:schemaLocation属性的值可以由多个URI引用对组成:
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.sunxin.org/bks bks.xsd http://www.sunxin.org/people people.xsd"> Schema推荐标准中指出,xsi:schemaLocation属性可以在实例中的任何元素上使用,而不一定是根元素,但必须出现在它要验证的任何元素和属性前面。 l xsi:noNamespaceSchemaLocation 用于引用没有目标空间的模式文档,它的值是单一的值,只用于指定模式文档的位置。 xsi:noNamespaceSchemaLocation="book.xsd" isbn="978-7-121-06812-6"> 注解 在Schema中可以使用“”,不过为了方便其他读者和应用程序来理解模式文档,Schema提供了三个元素来为模式提供注解。它们是xs:annotation、xs:documentation、xs:appinfo,其中xs:documentation和xs:appinfo是作为xs:annotation元素的子元素。xs:documentation元素用于旋转适合人阅读的信息,而xs:appinfo元素则用于工具、模式表和其他应用程序提供信息。 这是一份用于企业雇员信息描述的模式文档 xs:appinfo没有xml:lang属性。 简单类型 简单类型的元素只能包含字符数据,不能包含子元素,也不能包含属性。使用 xs:simpleType元素来定义。 XML Schema支持类型的派生,这和面向对象语言中对象的继承有些类似,但又不完全相同。XMLSchema类型的派生分为限制(xs:restriction)和扩展(xs:extension),通过限制派生的新类型的值范围是原类型值范围的子集,通过扩展可以为现有类型添加新的元素和属性。 对于简单类型,只有限制派生而没有扩展派生,我们只能通过限制一个现有的简单类型来派生一个新的简单类型。这些限制是通过http://www.w3.org/2001/XMLSchema名称空间中的一些元素(xs:restriction)来对派生类型进行约束的。 要定义新的简单类型,使用 xs:simpleType 元素,要对现有的基类型进行限制,使用xs:restriction元素。 自定义简单类型只能限制派生而不能扩展派生,通过限制派生得到的新的简单类型的值范围是其基类型值范围的子集。 内置简单类型 自定义简单类型 Schema中用来进行数据类型的约束元素,它们都有一个value属性: 范围:minInclusive(包含范围)、maxInclusive、minExclusive(不包含范围)、maxExclusive 长度:length、minLength、maxLength 精度:totalDigits、fractionDigits 枚举:enumeration 模式匹配:pattern 空白处理:whiteSpace 限制范围 限制长度 指定精度 枚举值 注,取值只能是枚举值中的一个,不能是组合,如果想引用多个,则只能使用列表类型,请参考后面。 模式匹配 空白处理 whiteSpace的有效值为:preserve、replace和collapse。 preserve:所有空白都被保留,数据类型xs:string的whiteSpace值就是preserve。 replace:值中出现的每一个制表符、换行、回车都用一个空格进行替换。数据类型xs:normalizedString的whiteSpace的值就是replace。 collapse:值中出现的每一个制表符、换行、回车都用一个空格进行替换,在替换后,所有连续空格都被压缩为一个空格,此外,前导空格和结尾空格都被删除。数据类型xs:token的whiteSpace值就是collapse。 注,whiteSpace只能用于基于字符串的类型。在实际应用,很少直接使用whiteSpace,而是选择已经具有whiteSpace的基类型,如:xs:string、xs:normalizedString、xs:token fixed属性 除了enumeration和pattern外,都有一个fixed属性,类型为boolean,默认为false,如果为true,派生类型将不能修改值。 列表类型 简单类型可分为三类:原子类型、列表类型(内置的有NMTOKENS、IDREFS、ENTITIES)、联合类型。 自定义列表类型 使用xs:list元素可自定义新的列表类型,使用itemType属性引用一个现有的原子类型。 不能使用现有的列表类型来创建新的列表类型,也不能使用复杂类型来创建新的列表类型。 也可在xs:list元素内部使用xs:simpleType子元素来指定匿名的原子类型: 限定列表类型 5个约束元素可应用于列表类型,它们是:length、minLength、maxLength、enumeration、pattern。 对列表使用length、minLength、maxLength: 对列表使用enumeration: 对列表使用pattern: 联合类型 联合类型可以包含多个原子类型或列表类型(甚至是其他联合类型),组成联合类型的简单类型称为它的成员类型,成员类型必须是简单类型,不能是复杂类型。 自定义联合类型 使用xs:union元素可自定义联合类型,该元素的memberTypes属性给出组成联合类型的所有成员类型,各个成员之间使用空白符分开,或在xs:union元素内使用一个或多个xs:simpleType子元素来指定匿名的成员类型。 使用memberTypes属性来定义联合类型: 符合上面模式的实例文档: 在xs:union元素内部使用xs:simpleType子元素来指定一个匿名简单类型作为联合类型的成员类型: 符合上面模式的实例文档: 限制联合类型 enumeration和pattern可以应用于联合类型。 注,也只能取枚举类型中的某一个值,不能是组合 注,其实enumeration与pattern也都可以写在union内部,但它们只能用在列表类型内部,否则不正确。 阻止简单类型派生 xs:smipleType的属性final可用来阻止派生,其取值如下: #all:表示阻止任何种类(限制、列表、联合)的派生 restriction:阻止限制派生 list:阻止列表派生 union:阻止联合派生 如果没有使用final属性,那么它的默认值将是xs:schema元素的finalDefault属性值,如果要取消finalDefault属性值,那么可以将xs:simpleType元素的final属性设置为空字符串 复杂类型 元素如果包含子元素或者带有属性则称为复杂类型,使用 xs:complexType元素来定义。 复杂类型要么具有简单内容,要么具有复杂内容。元素的“内容”是指在它的开始标签与结束标签之间的字符数据和子元素。简单内容指的是它只包含字符数据内容,而没有子元素(可以有属性),简单内容使用xs:simpleContent元素来定义;除此之外元素内容为复杂内容,使用xs:complexContent元素来定义。 简单内容类型(xs:simpleContent)的复杂元素要求必须含有文本,可以有属性,也可以没有,但不能有子元素。 复杂内容类型(xs:complexContent)的复杂元素可以有属性、子元素(没有子元素时就成空元素了),也可以没有,但不能有文本。 XMLSchema类型的派生分为限制(restriction)和扩展(extension),通过限制派生的新类型的值范围是原类型值范围的子集,通过扩展可以为现有类型添加新的元素和属性。 我们可以通过扩展(extension)为现有类型添加新的元素和属性,也可从xs:anyType类型限制派生(restriction)来定义新的复杂类型。 从简单内置类型派生复杂类型 对于 如果现为book元素添加一个属性isbn,则需要从内置简单类型派生出复杂类型: xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="例7-1.xsd"> 《Struts 2深入详解》 xs:attribute元素的use、default和fixed属性 use的取值如下: l optional:表明属性是可选的,默认值就是可选。 l prohibited:禁止使用这个属性。 l required:属性是必需的。 注,对于声明的全局属性不能使用use属性。 default用来设置元素属性的默认值,如果在XML文档中没有指定声明的这个属性,那么处理器就认为该属性的值等于声明中的default属性值。要注意,属性的默认值只有在属性本身为“optional”时才有意义,也就是说,属性使用默认值的时候,use属性的值只能是optional。 如果想让某个元素的属性值固定下来,不允许修改时,可以使用xs:attribute元素的fixed属性来指定一个固定的默认值。 注,default与fixed不能同时使用。 anyType anyType是派生所有简单和复杂类型的基类型,它是XML Schema中所有类型的祖先。如果一元素的类型具有anyType类型,那么它的内容将可以是任何形式。 实际上,anyType是默认类型,在声明一个元素时,如果没有指定类型时,就是该类型。 纯元素内容 如果元素的内容中只包含子元素,而没有字符数据,则为纯元素内容。我们可以使用模型组(xs:sequence、xs:choice、xs:all)来构建纯元素内容的内容模式。 xs:sequence 表示序列,sequence组中的所有子元素要按照指定的顺序出现。 xsi:noNamespaceSchemaLocation="例7-4.xsd"> XMLSchema规定,如果一个具有复杂内容的复杂类型定义是从anyType类型限制派生( xs:choice 表示选择,choice组中的所有子元素可以选择使用任意一个,且只能使用一个,且一定要有一个。 xsi:noNamespaceSchemaLocation="例7-7.xsd"> 组合使用sequence组和choice组: xs:all 表示任意次序,all组中的所有子元素可以以任意顺序出现,且都要出现。 xsi:noNamespaceSchemaLocation="例7-11.xsd"> xs:all组不能和其他的模型组(sequence组和choice组)一起使用(但可以有属性),而它必须出现在内容模型的顶部,下面违反了三条规则: 正确的只能这样: 元素的出现次数限制 可以使用两个属性:minOccurs和maxOccurs来指定元素出现的次数,这两个属性可以在 xs:element 或模型组元素(xs:sequence、xs:choice、xs:all)上使用,它们的默认值都是1。 在xs:element上使用minOccurs和maxOccurs: minOccurs="0" maxOccurs="unbounded"/> minOccurs="0" maxOccurs="unbounded"/> xsi:noNamespaceSchemaLocation="例7-14.xsd"> 在xs:sequence上使用minOccurs和maxOccurs: xsi:noNamespaceSchemaLocation="例7-14.xsd"> 在xs:choice上使用minOccurs和maxOccurs: 在all组中声明的元素都不能出现超过一次,也就是说,在使用xs:all元素定义的内容模型时,xs:all元素本身和其内的xs:element元素的minOccurs和maxOccurs属性值只能是0或1,xs:all元素的maxOccurs属性必须是1。 元素的默认值与固定值 除了属性以外,元素也有默认值,使用xs:element元素的default属性来定义默认值。 空元素 anyType是默认类型,在声明一个元素时,如果没有指定类型时,就是该类型。所以如果要定义一个空元素,则需要手工指定。 混合内容 如果一个元素既包含子元素,又包含字符数据,那么称元素的内容为混合内容。要定义混合内容类型,可以将xs:complexType元素的mixed属性设置为true。 xsi:noNamespaceSchemaLocation="例7-25.xsd"> 雇员: 年龄: 元素组 将多个元素定义在一个全局组里,供后面重用。 maxOccurs="unbounded"/> 注,xs:group元素中不能直接使用xs:element元素,必须先使用模型组。另外,xs:group元素本身和它内部模型组都不能使用出现指示符(minOccurs和maxOccurs属性),如果希望出现多次,可以在引用元素时使用( 属性组 元素通配符xs:any 实例文档中的xs:any元素出现的位置可以使用任意元素来替换,它有4个属性:minOccurs、maxOccurs、namespace和processContents。 minOccurs、maxOccurs属性用于控制替换元素出现的次数,但不包括替换元素的子元素,默认值都是1。 namespace属性用于指定替换元素所属的名称空间,默认值为 ##any,表示替换元素可以在任何名称空间,或不在任何名称空间。##other 表示替换元素可以在除模式文档目标名称空间之外的任何名称空间中,如果没有目标名称空间,则替换元素可以属于任何名称空间,且必须属于一个名称空间。除了这两个值外,还可以是下列值: ##targetNamespace:替换元素可以在模式文档的目标名称空间中。 ##local:替换元素不在任何名称空间中。 替换元素的特定名称空间:指出替换元素所在的名称空间URI,多个使用空白符分开。 注,名称空间约束只适用于替换元素,子元素根据替换元素本身的类型进行验证。 processContents属性用于指示模式处理器如何对替换元素进行验证,取值如下: strict:默认值。找namespace属性指定的模式文档,如果找不到或验证失败,则报错。 lax:如果找不到,则不报错,如果找到且验证失败,则报错。 skip:不执行任何验证,但替换元素必须在namespace属性所允许的一个名称空间中。 --例7-31.xsd elementFormDefault="qualified" attributeFormDefault="unqualified"> xsi:noNamespaceSchemaLocation="例7-31.xsd"> 将模式文档中的“ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="例7-31.xsd"> 如果将上面的skip改为lax,则“验证”还是可以通过,因为实例文档并没有给出与http://www.sunxin.org/family名称空间相关的模式文档的位置,所以解析器无法找到替换元素的声明来对替换元素进行验证,所以也不会报错。但如果修改成 strict 时,上面的实例文档将不能通过验证。 如果将上面的skip修改成strict,则实例文档中的children需要在某个模式文档进行声明过,否则验证不通过: --实例文档: xsi:noNamespaceSchemaLocation="例7-31.xsd" xsi:schemaLocation="http://www.sunxin.org/family family.xsd" xmlns:family="http://www.sunxin.org/family"> 上面实例文档中的元素声明来自两个模式文档:“例7-31.xsd”与“family.xsd”,在进行验证时,会到这两个模式文档中去是否对相应元素进行了声明,并进行有效行验证。 --family.xsd xmlns="http://www.sunxin.org/family" targetNamespace="http://www.sunxin.org/family"> 属性通配符xs:anyAttribute 实例文档中的xs:anyAttribute元素出现的位置可以使用任意属性来替换,它有2个属性: namespace和processContents,其意义与元素通配符作用完全相同。但xs:anyAttribute没有minOccurs、maxOccurs两个属性,因为属性通配符无须任何指定,就可以有任意多个替换属性。 xsi:noNamespaceSchemaLocation="例7-36.xsd" idCard="1001001980081021110" married="yes"> 派生复杂类型 在XMLSchema中没有内置的复杂类型,复杂类型都是通过限制或扩展其他的类型来派生的。 当从简单类型或另一个具有简单内容(元素内容只包含字符数据,可以有属性)的复杂类型派生复杂类型时,使用xs:simpleContent元素。如果是扩展派生(添加属性),则在xs:simpleContent元素内部使用xs:extension元素;如果是限制派生(限制基类型的内容),则在xs:simpleContent元素内部使用xs:restriction元素。 如果复杂类型具有简单内容,那么所有直接或间接派生于它的类型也只能具有简单内容,如果在派生的过程中试着将简单内容转换为复杂内容时,会报错,不能将简单内容转换成复杂内容: 复杂内容包括3种内容类型:纯元素类型、混合类型、空内容类型。 扩展派生复杂类型 扩展简单内容 扩展简单内容可以从简单类型扩展,也可以从具有简单内容的复杂类型进行扩展。由于不能通过扩展简单内容来得到复杂内容,因此对简单内容的扩展只能是添加新的属性。 xsi:noNamespaceSchemaLocation="例8-2.xsd" number="101" hiredate="2008-07-01">张三 扩展纯元素内容 从纯元素内容的复杂类型扩展,我们可以在基类型的内容模型最后添加新的元素或属性。解析器将把基类型的内容模型和新添加的内容模型合并到一个新建的sequence组中。 扩展empType类型后的expandedEmpType类型等价于下面的类型定义: xsi:noNamespaceSchemaLocation="例8-4.xsd"> 下面再看一个扩展choice组的例子: 上面我们本意是将peach和orange元素添加到基类型choice组中,以便可以在5个子元素中任意选择其中一个,但结果不是我们所想那样,它等价于下面类型: 也就是说,通过添加一个新的choice组来扩展choice组,其结果并不是两个choice组的元素合并在一起,而是产生了一个包含两个choice组的sequence组。 不能对一个包含all组的基类型进行扩展来添加新的元素(只添加属性是可以的),这是因为all组不能和其他模型组(xs:sequence组和choice组)一起使用,而且它必须出现在内容模型的顶部。 扩展混合内容 混合内容的扩展与纯元素内容的扩展类似,唯一要求是派生类型必须也是混合内容,也就是说,在定义派生类型时,xs:complexType元素的mixed属性也必须设为true。 xsi:noNamespaceSchemaLocation="例8-8.xsd"> 雇员: 年龄: 薪水: 扩展空内容 从空内容类型扩展,派生类型可以具有纯元素内容(通过添加元素),也可以具有混合内容(通过将派生类型的mixed属性设置为true)。 限制派生复杂类型 限制简单内容 与扩展简单内容不同,限制简单内容的基类型必须是具有简单内容的复杂类型,而不能是简单类型,因为简单类型的限制是另一个简单类型,而不是复杂类型。 xsi:noNamespaceSchemaLocation="例8-12.xsd" type="office">010-66668888 限制纯元素内容 可以限制元素的内容或属性的取值,及删除元素或属性,对于需要从基类型保留的元素和属性则需要重新声明。 限制混合内容 从具有混合内容的复杂类型限制派生,可以得到混合内容的复杂类型、纯元素内容的复杂类型、简单内容的复杂类型,甚至是空内容的复杂类型。 限制空内容 限制空内容只能对基类型的属性进行限制,派生类型也必须是空内容。 在实例文档中使用派生类型 在上面“限制空内容”节中的例子中(前面所有元素类型引用都是这样直接指定派生类型),都是为声明的元素直接指定派生类型,从而在实例文档中依照派生类型来为元素或属性设值,但我们也可以不在声明元素时直接指定派生类型,甚至不指定类型(默认为 ##anyType),而是在XML文档中使用时通过xsi:type属性来显式地指定类型。xsi:type属性是XMLSchema实例名称空间http://www.w3.org/2001/XMLSchema-instance的一部分。 xsi:noNamespaceSchemaLocation="例8-20.xsd">
替换组
替换组(substitution group),允许在模式中声明的某个元素被其他元素所替换。替换组由头元素和替换成员组成,头元素与它的替换成员都必须作为全局元素声明,替换成员必须与头元素有相同类型,或是头元素类型的派生类型。头元素是普通的全局元素,但它的替换成员则需要使用一个特殊的属性substitutionGroup,该属性用于指定要替换的头元素的名字。
修改上节例子:
。。。。。。。。。。。。。。。。。
xsi:noNamespaceSchemaLocation="例8-22.xsd">
抽象元素和类型
一个元素和类型可以被声明成抽象的,抽象元素和类型不能在实例文档中使用。将一个元素声明为抽象的,就需要使用替换组,在实例文档中用替换组成员来代替抽象元素,将一个元素对应的类型定义为抽象的,那么该元素的所有实例都必须使用xsi:type属性来指定一个非抽象的派生类型。
我们可以将上面例子中的“
再回到“在实例文档中使用派生类型”节中的例子,将“
”定义成抽象类型:
则下面的item元素无法通过验证:
而将 item 元素类型通过 xsi:type 来指定其派生类就可以了:
控制派生类型的创建和使用
可以使用xs:complexType元素的final属性来控制类型的派生,利用block属性来控制在实例文档中使用派生类型。
final取值如下:
l #all:阻止对该类型的任何形式(限制或扩展)的派生。
l extension:阻止对该类型的扩展派生。
l restriction:阻止对该类型限制派生。
l extension和restriction列表:等价于#all。
如果没有指定final属性,那它的值将是 xs:schema 元素的finalDefault属性的值。如果xs:schema元素指定了finalDefault属性,而在某个类型定义时我们想取消finalDefault属性的值,则可将该类型的final属性设为空字符串。block值也是这样的规则,只是使用bolockDefault而已。
block属性用于对派生类型在实例文档中的使用进行控制,取值如下:
l #all:阻止任何派生类型在实例文档中替换该类型。
l extension:阻止通过扩展派生的类型在实例文档中替换该类型。
l restriction:阻止通过限制派生的类型在实例文档中替换该类型。
l extension和restriction列表:等价于#all。
如果将“在实例文档中使用派生类型”节中的例子的“
”元素修改为“
除了可以在xs:complexType元素上使用block属性来控制派生类型在实例文档中的使用外,还可以在xs:element元素上使用block属性,作用与在xs:complexType上定义的是一样,除此外,其取值还可以是substitution,表示阻止替换组中的成员来替换该元素。
xsi:noNamespaceSchemaLocation="例8-24.xsd">
上面实例文档可以安全通过验证,但如果将address元素也加上属性xsi:type="derivedAddressType"时,则就不能通过验证,因为在模式文档中声明address元素时加上了block="extension"属性,所以阻止了该元素类型的扩展派生类型来替换原来的类型。
一致性约束
unique约束
确保某些元素或属性的值在某个特定的范围内是唯一的,它使用xs:unique元素来定义,其name属性指定约束名称。在xs:unique元素内部,必须按顺序包含下列元素:
l xs:selector元素:有一个必需的属性xpath,用于选择一个元素集,在其中由xs:field元素指定的值必须是唯一的。该元素必须且只能使用一次。
l xs:field元素:也有一个必须的属性xpath,其值为Xpath表达式,用于指定对于由xs:selector元素所选择的元素而言必须是唯一的值(元素或属性的值)。可以使用多个,如果使用了多个xs:field元素,那么它们所指定的元素属性值的组合必须是唯一的。
xmlns:comp="http://www.sunxin.org/company" targetNamespace="http://www.sunxin.org/company" elementFormDefault="qualified">
注,由于Xpath不支持默认名称空间,所以“xmlns ="http://www.sunxin.org/company"”需加上名称前缀“xmlns:comp="http://www.sunxin.org/company"”,而且在xpath属性的元素前需带上名称前缀,否则约束将不起作用:
xsi:schemaLocation="http://www.sunxin.org/company 例9-3.xsd" xmlns="http://www.sunxin.org/company">
key约束
与unique约束类似,只是key约束指定的元素或属性不能是可选的,它们在实例文档中必须存在,即使在模式文档中它们是可选的,但在实例文档中一定不能省掉。
key约束也是使用xs:selector与xs:field元素来定义的,使用与unique约束一样。
keyref约束
keyref约束必须和unique约束或者key约束一起使用,keyref约束类似数据库表外键约束,而unique约束或者key约束类似数据库表主键约束。
keyref约束使用xs:keyref元素来定义,除了name属性外,还有一个refer属性,用于引用模式文档中的unique或者key约束的名称,在该元素内部,必须按顺序包含下列子元素:
xs:selector元素、xs:field元素:其xpath属性用于指定unique或key约束中的元素或属性值的元素或属性。xxs:file元素的数目必须与它所引用的unique或key约束中的xs:field元素数据相同,顺序也要相同。
xsi:noNamespaceSchemaLocation="例9-10.xsd">
注,在组合使用keyref和key约束(或unique约束)时,被keyref约束引用的key约束(或unique约束)必须在同一个元素声明中定义,或在它的一个子元素声明中定义。keyref不能引用在兄弟元素或父元素声明中定义的key。
引入其他模式文档
包含xs:include
xmlns="http://www.sunxin.org/emp" targetNamespace="http://www.sunxin.org/emp">
xmlns:emp="http://www.sunxin.org/emp" targetNamespace="http://www.sunxin.org/emp">
使用包含的一个很重要的条件就是,被包含组件的目标名称空间必须和包含方的止标名称空间一样。实际上,被包含的模式文档也可以没有名称空间,将使用包含方的目标名称空间。如果包含方也没有目标名称空间,那么就和没有使用名称空间是一样的。
如果被包含模式文档中没有定义目标名称空间,而包含方包含了目标名称空间,在被包含模式文档中,类型引用、元素引用、组引用时都直接引用,因为被包含模式文档中没有名称空间,这是可以的,当它引入到包含方模式文档里后,虽然被包含模式文档已处理包含方定义的目标名称空间中了,但解析器还是可以处理。
可以使用xs:include元素包含多个模式文档,只不过它们的目标名称空间一要样,或者被包含的模式文档中都没有目标名称空间。
重定义xs:redefine
重定义与包含类型,也可引入其他模式文档,且都要求被引入的模式文档与包含方具有相同的名称空间(或者没有目标名称空间),不同的是重定义可以对引入的模式文档中的组件进行重新定义。
xmlns:emp="http://www.sunxin.org/emp" targetNamespace="http://www.sunxin.org/emp">
注,只有简单类型、复杂类型、元素组和属性组可以被重定义。只有需要重定义的组件才应该出现在xs:redefine元素中,其他组件将被直接包含到新的模式中。
导入xs:import
导入与包含的区别是,导入发生在不同的名称空间之间,被导入的模式文档和导入方必须具有不同的名称空间。
--address.xsd
xmlns="http://www.sunxin.org/address" targetNamespace="http://www.sunxin.org/address">
--employee.xsd
xmlns="http://www.sunxin.org/emp" xmlns:addr="http://www.sunxin.org/address" targetNamespace="http://www.sunxin.org/emp"> schemaLocation="address.xsd"/>
如果address.xsd没有声明目标名称空间,那么xs:import元素就不能使用namespace属性,这将导入不在任何名称空间中的组件。在这种情况下,应该将employee.xsd中的type="addr:addressType"改为type="addressType",然而,在本例中,这将出现模式验证错误。这是因为employee.xsd声明了默认的名称空间xmlns="http://www.sunxin.org/emp",type="addressType"将导致引用默认名称空间中的addressType类型,但默认名称空间中并没有定义这个类型,因此出现错误。要避免这个问题,一种方式是将xmlns=http://www.sunxin.org/emp名称空间绑定到一个前缀上,另一种方式是在声明homeAddress元素的xs:element元素上设置 xmlns=""。