一、什么是xml
XML是指可扩展标记语言(eXtensible Markup Language),它是一种标记语言,很类似HTML。
它被设计的宗旨是传输数据,而非显示数据。
XML标签没有被预定义,需要用户自行定义标签。
但是现在它使用最多还是作为我们的配置文件。例如,一个java web项目当中的web.xml就是一个配置文件。在一般的coding当中,我们经常使用xml来配置相关的东西。例如spring当中的配置文件就是xml格式的。
但是现在要讲的不是xml文件,而是xml文件的约束文档schema
二、schema
1、什么是schema
因为XML都是用户自定义的标签,若出现小小的错误,软件程序将不能正确地获取文件中的内容而报错。(如:Tomcat)
所以在xml技术中,可以编写一个文档来约束一个XML的书写规范,这个文档称之为约束也就是我们的schema了。当然了xml的约束文档有几种,例如以前的DTD,但是DTD逐渐的被schema替代了。因为schema文档具有如下特性:
- XML Schema针对将来的额外内容是可扩展的
- XML Schema内容比DTD丰富,作用也更大
- XML Schema是以XML语言编写而成的
- XML Schema支持数据类型
- XML Schema支持名称空间(namespaces)
2、如何使用xml schema
如下有一份简单的schema文件,我们来分别介绍。
<?xml version="1.0"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://www.w3schools.com"
elementFormDefault="qualified">
<xs:element name="note">
<xs:complexType>
<xs:sequence>
<xs:element name="to" type="xs:string"/>
<xs:element name="from" type="xs:string"/>
<xs:element name="heading" type="xs:string"/>
<xs:element name="body" type="xs:string"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
头部:
- 文件的开头必须是< ?xml version=”1.0”?>。虽然文件的后缀是xsd但是它是一个xml文件
- < schema>元素是每份XML Schema文件的根元素。
- 在scehma元素中xmlns:xs=”http://www.w3.org/2001/XMLSchema” 表示schema当中的元素和数据的种类来自于http://www.w3.org/2001/XMLSchema命名空间(namespace)。同时,xmlns:xs中的xs表示来自这个命名空间的元素和属性都必须带有前缀“xs:”
- targetNamespace=”http://www.w3schools.com”表示的是这份schema文件定义的元素来自于http://www.w3schools.com这个命名空间,个人理解是:表示这份schema文件是来自于http://www.w3schools.com的,是属于它的。
- xmlns=”http://www.w3schools.com”表示这份schema中的文件都在这个名称空间里面声明过了
- elementFormDefault=”qualified” 指明了由这份schema声明的XML实例文档里用到的任何元素,都必须是有效的名称空间(namespace qualified)。
内容:
- < xs:element name=”note”>这个表示定义一个元素,元素的name为note。
- < xs:complexType>表示符合类型的元素。这个标签在 < xs:element name=”note”>里面,说明这个note元素是一个符合类型的。
- < xs:sequence>表示有序列的,表示里面它包裹之下的元素的顺序是固定的,顺不能错。
- < xs:element name=”to” type=”xs:string”/>表示一个简单类型的元素。
这个schema文件的标签和表示的内容都说完了。下面介绍一下简单类型的元素,以及一些其他的属性。
3、简单元素
定义的语法为如下,在上面的例子中已近见过。
<xs:element name="xxx" type="yyy"/>
xml schema 本身有很多数据种类。最常见的种类有:
- xs:string 表示字符
- xs:decimal 表示小数
- xs:integer 表示整数
- xs:boolean 表示逻辑值
- xs:date 表示日期
- xs:time 表示时间
简单元素也有指定的默认值或固定值
下面例子里表示默认值是”red”:
<xs:element name="color" type="xs:string" default="red"/>
固定值是也是自动分派给属性的,并且,一旦有了固定值,你就不能指定其他值了。
下面例子里固定值是”red”:
<xs:element name="color" type="xs:string" fixed="red"/>
4、属性
一般的xml文件中,一个元素通常都会有属性,接下来看看schema中属性怎么定义。
定义语法:
<xs:attribute name="lang" type="xs:string"/>
属性的定义通常是在定义元素的标签里面。例如:
<xs:element name="shiporder">
<xs:complexType>
<xs:sequence>
<xs:element name="orderperson" type="xs:string"/>
<xs:element name="shipto">
<xs:complexType>
<xs:sequence>
<xs:element name="name" type="xs:string"/>
<xs:element name="address" type="xs:string">
<xs:element name="city" type="xs:string"/>
<xs:element name="country" type="xs:string"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
<xs:attribute name="orderid" type="xs:string" use="required"/>
</xs:complexType>
</xs:element>
同时,属性值有任何和必须之分,任意属性值表示可有可无,而必要属性值则表示必须存在的属性,使用“use”属性
<xs:attribute name="lang" type="xs:string" use="required"/>
属性值也有默认值和固定值,使用“default”来指定默认的属性值,使用“fixed”属性来指定固定值。
5、面
约束用于给XML元素或属性定义可接受的值,关于对XML元素的约束称之为“面(facet)”
1、对单个值的约束
下面的例子给叫做”age”的元件定义了一个“约束(restriction)”。“age”的值要大等于0,小等于120:
<xs:element name="age">
<xs:simpleType>
<xs:restriction base="xs:integer">
<xs:minInclusive value="0"/>
<xs:maxInclusive value="120"/>
</xs:restriction>
</xs:simpleType>
</xs:element>
2、对一组值的约束
<xs:element name="car">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:enumeration value="Audi"/>
<xs:enumeration value="Golf"/>
<xs:enumeration value="BMW"/>
</xs:restriction>
</xs:simpleType>
</xs:element>
上面的例子也可以写成这个样子:
<xs:element name="car" type="carType"/> <xs:simpleType name="carType">
<xs:restriction base="xs:string">
<xs:enumeration value="Audi"/>
<xs:enumeration value="Golf"/>
<xs:enumeration value="BMW"/>
</xs:restriction>
</xs:simpleType>
在这种情况下”carType”类型可以被其他元件所使用,因为它不是”car”元素的一部分
更多的约束请参看xmlSchema标准手册
6、指示器
用指示器(Indicators)我们可以控制文件中元素的使用方法
指示器有其中
1、顺序指示器(Indicators)
- All 全部
- Choice 选择
- Sequence 按顺序出现(前面提到过)
2、出现次数指示器
- max0ccurs 最多出现次数
- min0ccurs 最少出现次数
3、组指示器
- Group name 组名
- attributeGroup name 属性组名称
接下来顺序介绍
顺序指示器
顺序指示器(Indicators)用于指定元素的顺序。
1、< all>指示器(Indicators)指明了子元件可以以任何次序出现,并且每个子元件只能出现一次:
<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>
*用< all>指示器(Indicators)时你可以把< minOccurs>指示器(Indicators)设为0或1,< maxOccurs>指示器(Indicators)只能设为1(< minOccurs> 和 < maxOccurs> 我们后头再说)
*
2、选择指示器
< choice>指示器(Indicators)指明了随便的子元素都可以出现:
下面中的employee和employee都可以出现,或者不出现。
<xs:element name="person">
<xs:complexType>
<xs:choice>
<xs:element name="employee" type="employee"/>
<xs:element name="employee" type="member"/>
</xs:choice>
</xs:complexType>
</xs:element>
3、有序指示器
指定了子元素必须以一个指明的顺序出现:前面提到过,这里不再介绍。
出现次数指示器(Indicators)
出现次数指示器用于定义一个元素可以出现的次数
1、maxOccurs Indicator
最多出现次数指示器指明了一个元素可以出现的最多次数:
<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>
上面例子指明了“child_name”元素在“person”里面最多出现10次(默认值为1,即最多出现一次)
为使元件可以重复出现无数次,可以设置maxOccurs=”unbounded”的状态
2、minOccurs Indicator
最少出现次数指示器(Indicators)指明了一个元素要出现的最小次数
<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" minOccurs="0"/>
</xs:sequence>
</xs:complexType>
</xs:element>
上面的例子指明了”child_name”元素在”person”元素里最少出现0次(minOccurs的默认值为1),最多出现10次
下面给出一个实际的例子
名为”Myfamily.xml”的XML文件:
<?xml version="1.0" encoding="ISO-8859-1"?>
<persons xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="family.xsd">
<person>
<full_name>Hege Refsnes</full_name>
<child_name>Cecilie</child_name>
</person>
<person>
<full_name>Tove Refsnes</full_name>
<child_name>Hege</child_name>
<child_name>Stale</child_name>
<child_name>Jim</child_name>
<child_name>Borge</child_name>
</person>
<person>
<full_name>Stale Refsnes</full_name>
</person>
</persons>
下面给出”family.xsd”的schema文件:
<?xml version="1.0" encoding="ISO-8859-1"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
<xs:element name="persons">
<xs:complexType>
<xs:sequence>
<xs:element name="person" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:element name="full_name" type="xs:string"/>
<xs:element name="child_name" type="xs:string"
minOccurs="0" maxOccurs="5"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
其中元素person元素使用了最多出现次数指示器maxOccurs=”unbounded”表示出现的次数为无限多。full_name出现默认出现一次(即最多一次,最少一次)。child_name最多出现5次最少0次。
组指示器
组指示器(Indicators)用于定义相关的元素组。
必须在组声明里定义一个all, choice,或sequence元素。下面的例子定义了一个名为”persongroup”的组,这个定义了一组元素必须以一定顺序出现:
<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: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>
属性组
面的例子定义了叫做”personattrgroup”的一个属性组:
<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: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>
其他元素
1、< any>元素可以使我们在XML文档中添加没有被schema 定义过的新元素从而扩充XML文档。
下面的例子是名为”family.xsd”的一份XML schema片段。它展示了”person”元素的声明。用上< any>元素,我们可以在”person”元素的内容里扩充任意元素(在< lastname>的后面)
<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>
现在我们想在”person”元素中添加”children”元素,即使这篇schema的作者从未声明过什么”children”元素,我们也可以做到。
请看下面名为”children.xsd”的schema文件:
<?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文件(叫做”Myfamily.xml”),用上了来自”family.xsd” 和”children.xsd”两篇不同schema的组件
<?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文件是有效的,因为”family.xsd” schema允许我们在”person”元素里的”lastname”元素后面扩充一个任意元素。
2、< anyAttribute>元素可使我们在XML文档中添加未被schema指定过的属性。
例如
<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>
现在我们想在”person”元素中添加”gender”属性,即使这篇schema的作者从未声明过什么”gender”属性,我们也可以做到。添加一个新的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>
下面的XML文件(叫做”Myfamily.xml”),用上了来自”family.xsd” 和”attribute.xsd”两篇不同的schema组件。
<?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.xsdhttp://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>
< any> 和< anyAttribute>元素是用于制造可扩展文档的!它们允许文档含有没有在主要XML schema里声明过的其它新元素。
7、使用
通过上面的讲解和实例,差不读可以写一个简单的schem文档了,那我们怎么使用呢。其实上面的例子已经给出了,当我们不写名称空间的时候,在xml问使用xsi:noNamespaceSchemaLocation来添加schema文件。当然我们也可以添加自己的名称空间给我们自己使用