一、XML Schema 规范
1、简介:
1)XmlSchema 也是一种定义和描述Xml文档结构域内容的模式语言,其出现是为了克服DTD的局限性。
2)XmlSchema与DTD:
①、XmlSchema符合Xml语法结构,其就是一个Xml。Dom、Sax等api可以解析XmlSchema文档中的内容。
③、XmlSchema 比Xml DTD支持更多的数据类型,并支持用户自定义新的数据类型。如DTD不能规定文本的类型为数字、字母等,但是Schema可以细致的约束。
④、XmlSchema 不能像DTD一样定义实体(Entity),比DTD更加复杂。XmlSchema 正在取代DTD。
2、XML Schema 入门
1)XmlSchema也是一个xml文件,其扩展名通常为.xsd。
2)XmlSchema文档必须有一个根节点,并且这个根节点固定为<Schema>
3)一个XmlSchema,通常称为模式文档(约束文档),遵循这个文档写的xml称之为实例文档。
4)编写一个约束文档后,通常需要把则个文件中声明的元素绑定到一个URI地址上,即定义为一个命名空间,以后xml文件就可以通过这个URI(命名空间)来告诉解析引擎,xml文档中编写的元素来自哪里,被谁约束。
5)案例:
①、XmlSchema文件如下:具体语法先省略,先弄明白根元素中的属性的含义。
<?xml version="1.0" encoding="UTF-8"?> <schema xmlns="http://www.w3.org/2001/XMLSchema" targetNamespace="http://www.example.org/NewXMLSchema" xmlns:tns="http://www.example.org/NewXMLSchema" elementFormDefault="qualified"> <element name="书架"> <!--声明<书架>元素--> <complexType><!--声明<书架>元素为复杂类型--> <sequence maxOccurs="unbounded"><!--声明<书架>元素 sequence-有顺序; maxOccurs-无上限--> <element name="书"><!--声明<书>元素--> <complexType> <sequence> <element name="书名" type="string"></element><!--声明<书名>等元素的类型为string--> <element name="作者" type="string"></element> <element name="售价" type="string"></element> </sequence> </complexType> </element> </sequence> </complexType> </element> </schema> <!--声明的这个 schema 文件一定需要绑定要一个命名空间(即定义为一个Namespace,供其他xml文件使用): targetNamespace="http://www.example.org/NewXMLSchema"--> <!--elementFormDefault:"qualified"-定义的所有元素都绑定为这个命名空间; unqualified:表示只有根元素绑定为这个命名空间-->A、xmlns:引入命名空间(namespace):默认是W3C的。这个默认引用,只能出现一次。非默认引用需要加别名:如xmlns:tns="http://www.example.org/NewXMLSchema" ,增加了别名 tns 。一个文档可以引入多个命名空间。
B、targetNamespace:定义命名空间,其实XmlSchema的本质就是定义一个命名空间,共其他Xml引用。这边的命名空间定义为URI为"http://www.example.org/NewXMLSchema" ,引用的时候也必须是这个。
C、elementFormDefault:控制元素。有两个取值:"qualified"-定义的所有元素都绑定为这个命名空间; unqualified:表示只有根元素绑定为这个命名空间。
D、attributeFormDefault:控制属性的。用法与elementFormDefault一样。
②、引用这个Xml Schema 的Xml文件如下:
<?xml version="1.0" encoding="UTF-8"?> <书架 xmlns="http://www.example.org/NewXMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation = "http://www.example.org/NewXMLSchema NewXMLSchema.xsd"> <书> <书名>XML基础</书名> <作者>SAM-SHO</作者> <售价>28.00元</售价> </书> </书架> <!--xmlns="http://www.example.org/NewXMLSchema": 引入命名空间约束,只是虚的路径,需要 schemaLocation具体指定位置--> <!--xsi:schemaLocation: 指定具体的命名空间所指向的文件,需要具体路径 ,如d://a/NewXMLSchema.xsd 。又需要指定xsi是什么东西?--> <!--xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance": 指定 xsi 来自的命名空间为 W3C -->
A、xmlns:引入命名空间,默认使用方法(也可以使用别名)。这个地址只是"虚"的路径,需要 schemaLocation具体指定位置B、schemaLocation:辅助xmlns引入“实”的命名空间,指定具体的命名空间所指向的文件,需要具体路径。2部分组成:定义好的命名空间路径 + 具体schema文件的路径
C、xsi:schemaLocation的使用用到了xsi,所以使用xmlns:xsi指定为来自的命名空间为 W3C,固定用法。
③、我们再来简单看下Tomcat的web.xml文件中Xml Schema的使用:
<web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" version="2.5">
A、引入“虚”的命名空间:xmlns="http://java.sun.com/xml/ns/javaee"B、指定“实”的命名空间:xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
路径为:http://java.sun.com/xml/ns/javaee
具体Schema文件路径:http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd。我们自己亲自去下载这个文件。
C、指定xsi别名命名空间为来自W3C。
D、手动下载下来的web-app_2_5.xsd文档很大,我只把根元素贴出:
<?xml version="1.0" encoding="UTF-8"?> <xsd:schema xmlns="http://www.w3.org/2001/XMLSchema" targetNamespace="http://java.sun.com/xml/ns/javaee" xmlns:javaee="http://java.sun.com/xml/ns/javaee" xmlns:xsd="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" attributeFormDefault="unqualified" version="2.5">
3、XML Schema 语法
XML Schema 语言也称作 XML Schema 定义(XML Schema Definition,XSD)。XML Schema 语法在W3C的手册中非常详细,这边只简单介绍重要的几个语法。
1)简单的类型:——simpleType
①、简易元素:只包含文本的元素,它不会包含任何其他的元素或属性。
A、定义简易元素的语法:element 关键字
<xs:element name="xxx" type="yyy"/>此处 xxx 指元素的名称,yyy 指元素的数据类型。XML Schema 拥有很多内建的数据类型。最常用的类型为:xs:string xs:decimal xs:integer xs:boolean xs:date xs:time
B、例子:
简易元素定义:
<xs:element name="lastname" type="xs:string"/> <xs:element name="age" type="xs:integer"/> <xs:element name="dateborn" type="xs:date"/>
引用简易类型的XML 元素:如:<lastname>元素,文本类型为 “字符串”
<lastname>Smith</lastname> <age>28</age> <dateborn>1980-03-27</dateborn>
②、属性:简易元素无法拥有属性,假如某个元素拥有属性,它就会被当作某种复合类型。但是属性本身总是作为简易类型被声明的。
A、定义属性的语法 :attrribute 关键字
<xs:attribute name="xxx" type="yyy"/>在此处,xxx 指属性名称,yyy 则规定属性的数据类型。XML Schema 拥有很多内建的数据类型。
最常用的类型是:
xs:string xs:decimal xs:integer xs:boolean xs:date xs:time
B、例子
<xs:attribute name="lang" type="xs:string"/>
XML 元素:
<lastname lang="EN">Smith</lastname>
C、属性的默认值(default)和固定值(fixed)
当没有其他的值被规定时,默认值就会自动分配给元素。在下面的例子中,缺省值是 "EN":
<xs:attribute name="lang" type="xs:string" default="EN"/>
固定值同样会自动分配给元素,并且无法规定另外的值。在下面的例子中,固定值是 "EN":
<xs:attribute name="lang" type="xs:string" fixed="EN"/>
在缺省的情况下,属性是可选的。如需规定属性为必选,请使用 "use" 属性:
<xs:attribute name="lang" type="xs:string" use="required"/>
③、限定:restriction
用于为 XML 元素或者属性定义可接受的值。对 XML 元素的限定被称为 facet。
A、对值的限定:
下面的例子定义了带有一个限定且名为 "age" 的元素。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>
B、对一组值的限定:枚举enumeration
如需把 XML 元素的内容限制为一组可接受的值,我们要使用枚举约束(enumeration constraint)。
下面的例子定义了带有一个限定的名为 "car" 的元素。可接受的值只有:Audi,Golf,BMW:
<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>
上面的例子也可以被写为:这样可以达到通用的效果,在这种情况下,类型 "carType" 可被其他元素使用,因为它不是 "car" 元素的组成部分。
<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>
C、对一系列值的限定 正则pattern
如需把 XML 元素的内容限制定义为一系列可使用的数字或字母,我们要使用模式约束(pattern constraint)。
下面的例子定义了带有一个限定的名为 "letter" 的元素。可接受的值只有小写字母 a - z 其中的一个:
<xs:element name="letter"> <xs:simpleType> <xs:restriction base="xs:string"> <xs:pattern value="[a-z]"/> //只有小写字母 a - z 其中的一个 </xs:restriction> </xs:simpleType> </xs:element>
D、对空白字符的限定whitespace
如需规定对空白字符(whitespace characters)的处理方式,我们需要使用 whiteSpace 限定。
下面的例子定义了带有一个限定的名为 "address" 的元素。preserve,这意味着 XML 处理器不会移除任何空白字符。
replace,这意味着 XML 处理器将移除所有空白字符(换行、回车、空格以及制表符)。
collapse,这意味着 XML 处理器将移除所有空白字符(换行、回车、空格以及制表符会被替换为空格,开头和结尾的空格会被移除,而多个连续的空格会被缩减为一个单一的空格)。
<xs:element name="address"> <xs:simpleType> <xs:restriction base="xs:string"> <xs:whiteSpace value="preserve"/> // <xs:whiteSpace value="replace"/> <xs:whiteSpace value="collapse"/> </xs:restriction> </xs:simpleType> </xs:element>
E、对长度的限定
如需限制元素中值的长度,我们需要使用 length、maxLength 以及 minLength 限定。本例定义了带有一个限定且名为 "password" 的元素。其值必须精确到 8 个字符:
<xs:element name="password"> <xs:simpleType> <xs:restriction base="xs:string"> <xs:length value="8"/> </xs:restriction> </xs:simpleType> </xs:element>
这个例子也定义了带有一个限定的名为 "password" 的元素。其值最小为 5 个字符,最大为 8 个字符:
<xs:element name="password"> <xs:simpleType> <xs:restriction base="xs:string"> <xs:minLength value="5"/> <xs:maxLength value="8"/> </xs:restriction> </xs:simpleType> </xs:element>
F、数据类型的限定:
2)复杂的类型:——complexType
①、复合元素:
有两种方式来定义复合元素:如复合 XML 元素,"employee"。
<employee> <firstname>John</firstname> <lastname>Smith</lastname> </employee>A、通过命名此元素,可直接对"employee"元素进行声明,就像这样:
<xs:element name="employee"> <xs:complexType>//复杂元素 <xs:sequence>//有顺利 <xs:element name="firstname" type="xs:string"/>//包含的简易元素 <xs:element name="lastname" type="xs:string"/> </xs:sequence> </xs:complexType> </xs:element>只有"employee" 可使用所规定的复合类型,不能复用。
"firstname" 以及 "lastname",被包围在指示器 <sequence>中。这意味着子元素必须以它们被声明的次序出现。
B、"employee" 元素可以使用type属性,这个属性的作用是引用要使用的复合类型的名称:一般推荐这种写法。
<xs:element name="employee" type="personinfo"/> <xs:complexType name="personinfo"> <xs:sequence> <xs:element name="firstname" type="xs:string"/> <xs:element name="lastname" type="xs:string"/> </xs:sequence> </xs:complexType>上面所描述的方法,那么若干元素均可以使用相同的复合类型,提高了复用性。比如这样:
<xs:element name="employee" type="personinfo"/> <xs:element name="student" type="personinfo"/> <xs:element name="member" type="personinfo"/>
C、继承:可以在已有的复合元素之上以某个复合元素为基础(base、complexContent、extension),然后添加一些元素,就像这样:
<xs:complexType name="fullpersoninfo"> <xs:complexContent> <span style="color:#ff0000;"><xs:extension base="personinfo"></span> <xs:sequence> <xs:element name="address" type="xs:string"/> <xs:element name="city" type="xs:string"/> <xs:element name="country" type="xs:string"/> </xs:sequence> </xs:extension> </xs:complexContent> </xs:complexType>
②、复合空元素
A、
复合元素不能包含内容,只能含有属性。如,一个空的 XML 元素:
<product prodid="1345" />上面的 "product" 元素根本没有内容。为了定义无内容的类型,我们就必须声明一个在其内容中只能包含元素的类型,但是实际上我们并不会声明任何元素,比如这样:
<xs:element name="product"> <xs:complexType> <xs:complexContent> <xs:restriction base="xs:integer"> <xs:attribute name="prodid" type="xs:positiveInteger"/> </xs:restriction> </xs:complexContent> </xs:complexType> </xs:element>
分析:complexContent 元素:我们打算限定或者拓展某个复合类型的内容模型,而 integer 限定则声明了一个属性但不会引入任何的元素内容。B、利用 type 的写法如下:
// 简单写法 <xs:element name="product"> <xs:complexType> <xs:attribute name="prodid" type="xs:positiveInteger"/> </xs:complexType> </xs:element> // 使用 type 的写法 <xs:element name="product" type="prodtype"/> <xs:complexType name="prodtype"> <xs:attribute name="prodid" type="xs:positiveInteger"/> </xs:complexType>
③、仅含元素
A、Xml文档:
<person> <firstname>John</firstname> <lastname>Smith</lastname> </person>
B、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:complexType> </xs:element>
④、仅含文本-有属性和文本
使用simpleContent 元素。当使用简易内容时,我们就必须在 simpleContent 元素内定义扩展或限定
A、Xml文档:
<shoesize country="france">35</shoesize>
B、Schema限定:
<xs:element name="shoesize"> <xs:complexType> <xs:simpleContent> <xs:extension base="xs:integer"> <xs:attribute name="country" type="xs:string" /> </xs:extension> </xs:simpleContent> </xs:complexType> </xs:element>分析:声明了一个复合类型,其内容被定义为整数值,并且 "shoesize" 元素含有名为 "country" 的属性:
⑤、混合内容
A、Xml文档:
<letter> Dear Mr.<name>John Smith</name>. Your order <orderid>1032</orderid> will be shipped on <shipdate>2001-07-13</shipdate>. </letter>B、
<xs:element name="letter"> <xs:complexType mixed="true"> <xs:sequence> <xs:element name="name" type="xs:string"/> <xs:element name="orderid" type="xs:positiveInteger"/> <xs:element name="shipdate" type="xs:date"/> </xs:sequence> </xs:complexType> </xs:element>
分析:为了使字符数据可以出现在 "letter" 的子元素之间,mixed 属性必须被设置为 "true"。
<xs:sequence> 标签 (name、orderid 以及 shipdate ) 意味着被定义的元素必须依次出现在 "letter" 元素内部。⑥、指示器
通过指示器,我们可以控制在文档中使用元素的方式。有七种指示器(前五种常用):
A、Order 指示器:Order 指示器用于定义元素的顺序。
Ⅰ、<all> 指示器规定子元素可以按照任意顺序出现,且每个子元素必须只出现一次:
<xs:element name="person"> <xs:complexType> <span style="color:#3333ff;"><xs:all></span> <xs:element name="firstname" type="xs:string"/> <xs:element name="lastname" type="xs:string"/> <span style="color:#3333ff;"> </xs:all></span> </xs:complexType> </xs:element>注释:
当使用 <all> 指示器时,你可以把 <minOccurs> 设置为 0 或者 1,而只能把 <maxOccurs> 指示器设置为 1
Ⅱ、<choice> 指示器规定可出现某个子元素或者可出现另外一个子元素(非此即彼):
<xs:element name="person"> <xs:complexType> <span style="color:#3333ff;"><xs:choice></span> <xs:element name="employee" type="employee"/> <xs:element name="member" type="member"/> <span style="background-color: rgb(51,51,255);"> </xs:choice></span> </xs:complexType> </xs:element>分析:<employee><member>两个元素, 非此即彼。如需设置子元素出现任意次数,可将 <maxOccurs> (稍后会讲解)设置为 unbounded(无限次)。
Ⅲ、<sequence> 规定子元素必须按照特定的顺序出现:前面的例子很多。
B、Occurrence 指示器:用于定义某个元素出现的频率。
Ⅰ、<maxOccurs> 指示器可规定某个元素可出现的最大次数:
<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" 元素中最少出现一次(其中 minOccurs 的默认值是 1),最多出现 10 次。
Ⅱ、<minOccurs> 指示器可规定某个元素能够出现的最小次数:
<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 次,最多出现 10 次。
Ⅲ、如需使某个元素的出现次数不受限制,请使用 maxOccurs="unbounded" 这个声明:
3)实际例子:
①、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>Tony Smith</full_name> <child_name>Cecilie</child_name> </person> <person> <full_name>David Smith</full_name> <child_name>Jogn</child_name> <child_name>mike</child_name> <child_name>kyle</child_name> <child_name>mary</child_name> </person> <person> <full_name>Michael Smith</full_name> </person> </persons>
②、Schena限定:family.xsd
<?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>