XSD学习记录
主要来自菜鸟教程的学习笔记,结合其他博客作了一些综合的学习,对最基本的内容整理了本markdown格式的单文档。
概念
- 全称
XML Schema Definition,作用是定义 XML 文档的合法构建模块,类似DTD. - 示例
请看这个名为 “note.xml” 的 XML 文档:
下面这个例子是一个名为 “note.xsd” 的 XML Schema 文件,它定义了上面那个 XML 文档( “note.xml” )的元素:<?xml version="1.0"?> <note> <to>Tove</to> <from>Jani</from> <heading>Reminder</heading> <body>Don't forget me this weekend!</body> </note>
<?xml version="1.0"?> <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="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 文档中引用 Schema
以下的这个XML文档(为maven项目的pom文件)含有对XML Schema的引用
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
……
</project>
下面的代码片断:
xmlns="http://maven.apache.org/POM/4.0.0"
规定了默认命名空间的声明。此声明会告知schema验证器,在此XML文档中使用的所有元素都被声明于"http://maven.apache.org/POM/4.0.0"这个命名空间。
现在来看文件头中剩下的,看上去更为复杂的部分:
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"
根据之前的知识我们可以理解,xmlns:xsi
定义了一个命名空间前缀xsi,对应的唯一字符串http://www.w3.org/2001/XMLSchema-instance
。但是读者会发现,这个xmlns:xsi
在不同的xml文档中似乎都会出现。这是因为,xsi 已经成为了一个业界默认的用于 XSD((XML Schema Definition) 文件的命名空间。
那么, 有了上述的理解, 再来看
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"
上面这行的语法其实是, xsi:schemaLocation = "键" “值”
即xsi命名空间下schemaLocation
元素的值为一个由空格分开的键值对
- 前一个“键”
http://maven.apache.org/POM/4.0.0
指代【命名空间】,只是一个全局唯一字符串而已. - 后一个值指代 【XSD location URI】 , 这个值指示了前一个命名空间所对应的 XSD 文件的位置, xml parser 可以利用这个信息获取到 XSD 文件, 从而通过 XSD 文件对
所有属于 命名空间http://maven.apache.org/POM/4.0.0
的元素结构进行校验, 因此这个值必然是可以访问的, 且访问到的内容是一个 XSD 文件的内容
XSD <schema>元素 (根元素)
<schema> 元素是每一个 XML Schema 的根元素。
<?xml version="1.0"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://www.runoob.com"
xmlns="http://www.runoob.com"
elementFormDefault="qualified">...
...
</xs:schema>
以下代码片段:
xmlns:xs="http://www.w3.org/2001/XMLSchema"
显示 schema 中用到的元素和数据类型来自命名空间 “http://www.w3.org/2001/XMLSchema”。同时它还规定了来自命名空间 “http://www.w3.org/2001/XMLSchema” 的元素和数据类型应该使用前缀 xs:
这个片段:
targetNamespace="http://www.runoob.com"
显示被此 schema 定义的元素 (note, to, from, heading, body) 来自命名空间: “http://www.runoob.com”。
这个片断:
xmlns="http://www.runoob.com"
指出默认的命名空间是 “http://www.runoob.com”。
这个片断:
elementFormDefault="qualified"
指出任何 XML 实例文档所使用的且在此 schema 中声明过的元素必须被命名空间限定。
XSD 简易元素
- 什么是简易元素?
简易元素指那些仅包含文本的元素。它不会包含任何其他的元素或属性。
不过,"仅包含文本"这个限定却很容易造成误解。文本有很多类型。它可以是XML Schema定义中包括的类型中的一种(布尔、字符串、数据等等),或者它也可以是您自行定义的定制类型。
您也可向数据类型添加限定(即facets),以此来限制它的内容,或者您可以要求数据匹配某种特定的模式。 - 定义简易元素
定义简易元素的语法:<xs:element name="xxx" type="yyy"/>
此处 xxx 指元素的名称,yyy指元素的数据类型。XML Schema拥有很多内建的数据类型。 - 最常用的类型是:
xs:string
xs:decimal
xs:integer
xs:boolean
xs:date
xs:time - 实例
这是一些 XML 元素:
这是相应的简易元素定义:<lastname>Refsnes</lastname> <age>36</age> <dateborn>1970-03-27</dateborn>
<xs:element name="lastname" type="xs:string"/> <xs:element name="age" type="xs:integer"/> <xs:element name="dateborn" type="xs:date"/>
- 简易元素的默认值和固定值
简易元素可拥有指定的默认值或固定值。当没有其他的值被规定时,默认值就会自动分配给元素。
在下面的例子中,默认值是 “red”:<xs:element name="color" type="xs:string" default="red"/>
固定值同样会自动分配给元素,并且您无法规定另外一个值。
在下面的例子中,固定值是 “red”:<xs:element name="color" type="xs:string" fixed="red"/>
XSD 属性(attribute)
所有的属性均作为简易类型来声明。
- 什么是属性?
简易元素无法拥有属性。假如某个元素拥有属性,它就会被当作某种复合类型。但是属性本身总是作为简易类型被声明的。
-
如何声明属性?
定义属性的语法是<xs:attribute name="xxx" type="yyy"/>
在此处,xxx 指属性名称,yyy则规定属性的数据类型。XML Schema 拥有很多内建的数据类型。 -
实例
这是带有属性的 XML 元素:<lastname lang="EN">Smith</lastname>
这是对应的lang属性定义:<xs:attribute name="lang" type="xs:string"/>
-
属性默认值/固定值/可选/必选
XSD 限定(Facets)
限定(restriction)用于为XML元素或者属性定义可接受的值。对XML元素的限定被称为facet。
- 对值的限定
下面的例子定义了带有一个限定且名为 “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>
其它限制模式还有很多,不在深入研究
XSD 复合元素
复合元素包含了其他的元素及/或属性。
-
什么是复合元素?
复合元素指包含其他元素及/或属性的 XML 元素。 -
有四种类型的复合元素:
空元素
包含其他元素的元素
仅包含文本的元素
包含元素和文本的元素
注意:上述元素均可包含属性! -
复合元素的例子
- 复合元素,“product”,是空的:
<product pid="1345"/>
- 复合元素,“employee”,仅包含其他元素:
<employee> <firstname>John</firstname> <lastname>Smith</lastname> </employee>
- 复合 XML 元素,“food”,仅包含文本:
<food type="dessert">Ice cream</food>
- 复合XML元素,"description"包含元素和文本:
<description> It happened on <date lang="norwegian">03.03.99</date> .... </description>
- 复合元素,“product”,是空的:
如何定义复合元素
请看这个复合 XML 元素,“employee”,仅包含其他元素:
<employee>
<firstname>John</firstname>
<lastname>Smith</lastname>
</employee>
在 XML Schema 中,我们有两种方式来定义复合元素:
-
通过命名此元素,可直接对"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>
中。这意味着子元素必须以它们被声明的次序出现。您会在XSD 指示器
这一节学习更多有关指示器的知识。 -
“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"/> <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="fullpersoninfo"/> <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:complexType name="fullpersoninfo"> <xs:complexContent> <xs:extension base="personinfo"> <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>
XSD 指示器
通过指示器,我们可以控制在文档中使用元素的方式。
-
指示器,有七种指示器:
Order指示器:- All
- Choice
- Sequence
Occurrence指示器:
- maxOccurs
- minOccurs
Group指示器:
- Group name
- attributeGroup name
Order指示器
Order 指示器用于定义元素的顺序。
-
All 指示器
<all>
指示器规定子元素可以按照任意顺序出现,且每个子元素必须只出现一次:<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>
指示器时,你可以把<minOccurs>
设置为0 或者1,而只能把<maxOccurs>
指示器设置为 1(稍后将讲解 minOccurs 以及<maxOccurs)。 -
Choice 指示器
<choice>
指示器规定可出现某个子元素或者可出现另外一个子元素(非此即彼): -
Sequence 指示器
<sequence>
规定子元素必须按照特定的顺序出现:
Occurrence指示器
Occurrence 指示器用于定义某个元素出现的频率。
注意:
对于所有的 “Order” 和 “Group” 指示器(any、all、choice、sequence、group name 以及 group reference),其中的 maxOccurs 以及 minOccurs 的默认值均为 1。
-
maxOccurs 指示器
<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 指示器
<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” 这个声明:
Group 指示器
Group指示器用于定义相关的数批元素。
个人理解: 数批元素表示元素/
-
元素组
元素组通过 group 声明进行定义,必须在 group声明内部定义一个all、choice 或者 sequence元素。
下面这个例子定义了名为"persongroup"的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>
在您把 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>
-
属性组
属性组通过 attributeGroup 声明来进行定义。下面这个例子定义了名为 “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>