XML学习笔记(七)Schema语法杂项

Preface:本文是W3Schools上《Schema指南》的学习笔记。其中大部分内容是对指南的翻译总结。由于原文的例子更详尽生动,如果各位想阅读原文可以到这个网址http://www.w3schools.com/schema/default.asp。同时,W3Schools提供了测试,大家可以测试一下自己的理解程度。

一、XSD Indicators(指示器)

指示器是用来说明Element在文档中应该如何使用的。这样的说法会比较抽象。看例子就很容易明白了。其实在之前的例子中我们已经用到了Indicator。只是在这里会体系的介绍。
在Schema中有7种的Indicator,分为3类
Order Indicators(顺序指示器):All、Choice、Sequence
Occurrence Indicators(发生指示器):maxOccurs、minOccurs
Group Indicators(组指示器):Group name、atrributeGroup name

OrderIndicators
顺序指示器的一般用法是这样的

<xs:element name="person">
<xs:complexType>
<xs:all>
<xs:element name="firstname" type="xs:string"/>
<xs:element name="lastname" type="xs:string"/>
</xs:all>
</xs:complexType>
</xs:element> 

注意以上的<xs:all>就是一个Indicator了。可以将其替换成sequence或choice。当然各自的含义是不同的。
all:子元素可以以任何的顺序出现,而且必须只出现一次。注意如果用了<all>那么<minOccurs>就只能设为0或1,<maxOccurs>只能设为1。
choice:所有的子元素中只能出现一个。
sequence:子元素必须按照定义的顺序出现。

OccurrenceIndicators
发生指示器用于指定元素的出现次数。作为元素的属性出现。用法如下:

<xs:element name="person">
<xs:complexType>
<xs:sequence>
<xs:element name="full_name" type="xs:string"/>
<xs:element name="child_name" type="xs:string" maxOccurs="10"/>
</xs:sequence>
</xs:complexType>
</xs:element> 

<maxOccurs>指定最多可以出现的次数。<minOccurs>指定最少出现的次数。如果使用了其他指示器那么OccurenceIndicators默认为1。当然可以同时使用<maxOccurs>和<minOccurs>来限定一个范围。如果要设定出现的最大次数为无限可以设maxOccurs="unbounded"。

GroupIndicators
组指示器是用于定义和元素相关的一组集合的。定义好GroupInicators后会在complexType中加入<group>或<attributeGroup>并使用ref属性指明引用的组。
Group name Indicator

<xs:group name="persongroup">
<xs:sequence>
<xs:element name="firstname" type="xs:string"/>
<xs:element name="lastname" type="xs:string"/>
<xs:element name="birthday" type="xs:date"/>
</xs:sequence>
</xs:group>
<xs:element name="person" type="personinfo"/>
<xs:complexType name="personinfo">
<xs:sequence>
<xs:group ref="persongroup"/>
<xs:element name="country" type="xs:string"/>
</xs:sequence>
</xs:complexType> 

注意在定义group时必须使用一个OrderIndicator。
attributeGroup name

<xs:attributeGroup name="personattrgroup">
<xs:attribute name="firstname" type="xs:string"/>
<xs:attribute name="lastname" type="xs:string"/>
<xs:attribute name="birthday" type="xs:date"/>
</xs:attributeGroup>
<xs:element name="person">
<xs:complexType>
<xs:attributeGroup ref="personattrgroup"/>
</xs:complexType>
</xs:element> 

二、<any>和<anyAttribute>

<any>元素可以让我们使用没有在Schema中定义的元素去扩展XML文档。例如,在Schema family.xsd中使用了<any>

<xs:element name="person">
<xs:complexType>
<xs:sequence>
<xs:element name="firstname" type="xs:string"/>
<xs:element name="lastname" type="xs:string"/>
<xs:any minOccurs="0"/>
</xs:sequence>
</xs:complexType>
</xs:element> 

那么我们就可以在实际的XML文档中在<any>的位置插入任意的其他的没有定义的Element。例如我们有另一个Schema chile.xsd如下,

<?xml version="1.0" encoding="ISO-8859-1"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace
="http://www.w3schools.com"
xmlns
="http://www.w3schools.com"
elementFormDefault
="qualified">
<xs:element name="children">
<xs:complexType>
<xs:sequence>
<xs:element name="childname" type="xs:string"
maxOccurs
="unbounded"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema> 

那么我们可以保证下面的XML文档是有效的。

<?xml version="1.0" encoding="ISO-8859-1"?><persons xmlns="http://www.microsoft.com"
xmlns:xsi
="http://www.w3.org/2001/XMLSchema-instance"
xsi:SchemaLocation
="http://www.microsoft.com family.xsd
http://www.w3schools.com children.xsd"
>
<person>
<firstname>Hege</firstname>
<lastname>Refsnes</lastname>
<children>
<childname>Cecilie</childname>
</children>
</person>
<person>
<firstname>Stale</firstname>
<lastname>Refsnes</lastname>
</person>
</persons>

以上的XML引用了两个xsd。而由于在主Schema中使用了<any>,所以可以插入其他的Element,如上面的<children>。

同样<anyAttribute>允许在XML文档中为元素添加没有定义的Attribute。
仍然使用例子说明,首先有一个family.xsd定义如下,注意<anyAttribute>的位置。

<xs:element name="person">
<xs:complexType>
<xs:sequence>
<xs:element name="firstname" type="xs:string"/>
<xs:element name="lastname" type="xs:string"/>
</xs:sequence>
<xs:anyAttribute/>
</xs:complexType>
</xs:element> 

然后,我们在另一个attribute.xsd定义有属性,

<?xml version="1.0" encoding="ISO-8859-1"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace
="http://www.w3schools.com"
xmlns
="http://www.w3schools.com"
elementFormDefault
="qualified">
<xs:attribute name="gender">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:pattern value="male|female"/>
</xs:restriction>
</xs:simpleType>
</xs:attribute>
</xs:schema>

由于有<anyAttribute>的定义,所以可以保证如下的XML的有效性。

<?xml version="1.0" encoding="ISO-8859-1"?><persons xmlns="http://www.microsoft.com"
xmlns:xsi
="http://www.w3.org/2001/XMLSchema-instance"
xsi:SchemaLocation
="http://www.microsoft.com family.xsd
http://www.w3schools.com attribute.xsd"
>
<person gender="female">
<firstname>Hege</firstname>
<lastname>Refsnes</lastname>
</person>
<person gender="male">
<firstname>Stale</firstname>
<lastname>Refsnes</lastname>
</person>
</persons> 

三、XSD Element Substitution(替代元素)

由于XML用户是不确定的,尤其可能会涉及到不同国家的问题,很多时,为了方便编写XML的用户,我们可以在Schema中预先定义一些允许替换的元素。允许在编写XML时使用Element的别名,而不影响有效性。方法是使用“substitutionGroup”。例如,一个XML的主要用户是英格兰和挪威。那么可以在Schema中定义:

<xs:element name="name" type="xs:string"/>
<xs:element name="navn" substitutionGroup="name"/>
<xs:complexType name="custinfo">
<xs:sequence>
<xs:element ref="name"/>
</xs:sequence>
</xs:complexType>
<xs:element name="customer" type="custinfo"/>
<xs:element name="kunde" substitutionGroup="customer"/> 

则如下的两种XML写法都是有效的,

<customer>
<name>John Smith</name>
</customer> 
<kunde>
<navn>John Smith</navn>
</kunde> 

如果不想Element有替代名称,可以使用如下的语句锁定元素不允许替代。
<xs:element name="name" type="xs:string" block="substitution"/>
这样,对名为name的替代定义将不会生效。

最后给出一个综合的例子,大家可以阅读这个例子回忆,之前介绍的语法。
http://www.w3schools.com/schema/schema_example.asp

本文为个人原创,转载请注明出自:http://jackma.cnblogs.com/
Author:JackMa

原文地址:https://www.cnblogs.com/JackMa/p/1212499.html