今天学了Schema,好好写篇博客总结一下。主要学了一下内容
Schema概述
Schema的格式和使用
Schema元素的声明
Schema的属性声明
Schema的数据类型
Schema的名称空间
Schema概述
我们知道DTD是用来限制XML文档格式,但是DTD相对来说有以下几个缺点:
DTD不同于XML的语言编写,需要不同的分析器技术。这增加了工具开发商的负担
DTD不支持名称空间
DTD在支持继承和子类方面的局限性:不能再已经写好的DTD再进行继承改进、只能重新写
DTD没有数据类型的概念,无法对特定元素施加数据类型,对强制性结构化无计可施,例如没办法限制价格是固定的数值型。
Schema就是对DTD的改进,客服了DTD的这些缺点。Schema的本义是“模版” 引申义是“模式”,在数据库中有“数据库表结构”的意思。对于Schema我们应该还要知道的是 XML Schema是用一套预先规定的XML元素和属性创建
Schema的格式和使用
简单的看一个XML文档和约束它的Schema代码
xml文档
<?xml version="1.0" encoding="UTF-8" ?>
<book
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="demo1.xsd"
id="011-22332-56"
>
<title>计算机导论</title>
<author>Jack</author>
<author>张三</author>
<publish>
<publisher>高等教育出版社</publisher>
<pubdate>2017-05-19</pubdate>
</publish>
<price>19.87</price>
</book>
schema
<?xml version="1.0" encoding="UTF-8"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xsd:element name="book" >
<xsd:complexType>
<xsd:sequence>
<xsd:element name="title" type="xsd:string"></xsd:element>
<xsd:element name="author" type="xsd:string" minOccurs="2" maxOccurs="4"></xsd:element>
<xsd:element name="publish" >
<xsd:complexType>
<xsd:sequence>
<xsd:element name="publisher" type="xsd:string"></xsd:element>
<xsd:element name="pubdate" type="xsd:date"></xsd:element>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<xsd:element name="price" type="xsd:double" ></xsd:element>
</xsd:sequence>
<xsd:attribute name="id" type="xsd:string"></xsd:attribute>
</xsd:complexType>
</xsd:element>
</xsd:schema>
Schema的作用
Schema文档用来验证XML文档的正确性,用来判断实例是否符合模式中所描述的所有约束,涉及到检查实例中所有的元素和属性。
Schema主要检验如下内容:
- 验证数据的显示格式是否正确及是否超出值的范围;
- 验证所有必需的信息都存在;
- 确保不同使用者对文档理解的方式相同。
除了对XML文档的验证外,Schema文档还在一定程度上扩充实例:
- 为元素和属性添加默认值和固定值;
- 使具有简单类型的元素和属性值中的空白符规范化
Schema的引用
一个模式可能由多个模式文档构成。多个模式文档通过包含或导入机制来形成模式,当其他模式文档与主模式文档具有相同的目标名称空间时,需要使用包含;当模式文档之间各自拥有不同的目标名称空间时,需要使用导入。
一个schema可能由多个schema构成,每个schema都有自己的名称空间,当主schema的名称空间和要并入的schema的名称空间相同是,用包含include ,不同时用导入import
<?xml version="1.0" encoding="gb2312" ?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns="http://example.org/ord"
targetNamespace="http://example.org/ord">
<xsd:include schemaLocation="moreBookInfo.xsd"/>
<xsd:import namespace="http://example.org/ord" schemaLocation="publish.xsd" />
<!--…-->
</xsd:schema>
关于名称空间还有以下几个知识点。
第一个是:xml文档里的这一句
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
第二个是:schema文档
schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
以一段小代码
<xsd:element name="publish" >
<xsd:complexType>
<xsd:sequence>
<xsd:element name="publisher" type="xsd:string"></xsd:element>
<xsd:element name="pubdate" type="xsd:date"></xsd:element>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
里面的element、complexType 都是W3C写的被限制的有特定意义的元素,与我们自己写的普通element、complexType不同。所以我们就需要前面导入w3c的名称空间。说明这些元素时w3c,才能有它特定的意义。
还有一个知识点就是 我们自己的名称空间
如果Schema文档包含了一个targetNamespace 属性,在XML文档中就将通过schemaLocation属性而不是noNamespaceSchemaLocation属性来引用Schema文档。而且,这个属性所指定的值必须是完整的。它需要包含以空格分开的两部分,前一部分是URI,这个URI与Schema文档的targetNamespace属性内部引用的URI是一致的;后一部分是Schema文件的完整路径及名称。
schema中没有targetNamespace属性是,xml中间可以直接用
xsi:noNamespaceSchemaLocation="demo1.xsd"
Schema元素的声明
element元素: XSD中的元素是利用element来声明的。其中name属性是元素的名字,type属性是元素值的类型,在这里可以是XML Schema中内置的数据类型或其他类型。具体定义格式如下:
<xsd:element name=“author” type=“xsd:string” />
要注意的是:name是元素类型的名称,必须是以字母或下划线开头,而且只能够包含字母、数字、下划线、连接符及句号。type属性是必要的,说明元素的数据类型。
全局元素:父元素是schema的元素
局部元素:只出现在复杂类型定义的内部
设置默认值和固定值
<xsd:element name="author" type="xsd:string" default="佚名"/>
设定固定值例子
<xsd:element name="author" type="xsd:string" fixed="1"/>
<xsd:element name="price" type="xsd:integer" fixed="1"/>
引用元素和替代
引用是利用element元素的ref属性实现的。主要适用于避免在文档中多次定义同一个元素,应当将经常使用的元素定义为根元素的子元素,即为全局元素,这样方便在文档的任何地方引用它
**引用:**ref=”author”
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xsd:element name="author" type="xsd:string"/>
<xsd:element name="book">
<xsd:complexType>
<xsd:sequence>
<xsd:element ref="author" />
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:schema>
替代:substitutionGroup=”author”
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xsd:element name="writer" type=xsd:string" substitutionGroup="author" />
<xsd:element name="author" type="xsd:string"/>
<xsd:element name="book">
<xsd:complexType>
<xsd:sequence>
<xsd:element ref="author" />
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:schema>
以上文档对应的有效XML文档如下:
<?xml version="1.0"?>
<book>
<author>罗贯中</author>
</book>
或者
<?xml version="1.0"?>
<book>
<writer>string</writer>
</book>
Schema的属性声明
实现的方法是使用attribute元素
创建属性
定义属性的方法如下:
<xsd:attribute name="isbn" type="xsd:string"/>
use属性用于指示属性是必需的还是可选的
<xsd:attribute name="isbn" type="xsd:string" use="required"/>
* 为属性指派类型*
属性声明有3种方式:
- 在属性声明中通过用type属性指定命名简单类型。它可以是内置类型,也可以是用户自定义类型。: 类似 java中的基本类型引用
- 通过指定simpleType子属性来指定匿名类型:其实挺复杂的,等下可以看到
既没有type属性,又没有simpleType子属性,从而不指定特定类型。在这种情况下,属性的类型为anySimpleType,它可以拥有任何值,只有它是结构合理的XML文档。
下例显示4个属性的声明,采用了不同的类型指定方法。定义了grade属性并赋予gradeType类型,amount属性指定了内置类型integer,同时使用内嵌的匿名简单类型来声明bookcategory属性,anything属性没有指定特定的类型。
Schema的数据类型
简单类型
简单类型的种类:
- 原子类型具有不可分割的值,
- 列表类型的值为用空格符隔开的原子值列表,如
<availableSizes>10 large 2</available Sizes>
- 联合类型的值可以是原子值,也可以是列表值。它们的区别在于该类型的有效值集是两个或多个其他简单类型值空间的联合。如要对学生的成绩评定等级,可以定义一个联合类型,它允许的值既可以是0~100的整数,也可以是优、良、合格或不合格。
新的简单类型可以通过从现有的简单类型(内置的简单类型以及源于内置简单类型的简单类型)引出定义
假设希望建立一个新的整数类型称为myInteger,它的值范围为10000~99999。那么定义应当基于简单类型integer,然后定义它的值范围为10000~99999。为了定义myInteger,这样来约束integer的范围,示例如下:
(说明:若是定义成全局则是name,局部则是id)
<xsd:simpleType name="myInteger">
<xsd:restriction base="xsd:integer">
<xsd:minInclusive value="10000"/>
<xsd:maxInclusive value="99999"/>
</xsd:restriction>
</xsd:simpleType>
restriction元素来指出现有的基类型,并且用它来标识约束值范围的细节
对myInteger类型进一步限制
<xsd:simpleType name="bookInteger">
<xsd:restriction base="xsd:myInteger">
<xsd:minInclusive value="23"/>
<xsd:maxInclusive value="2046"/>
</xsd:restriction>
</xsd:simpleType>
简单类型定义时,都是通过restriction元素来定义限制,通过base属性来规定一种基类型。在restriction内,可以任何顺序指定任何面(facet),来对类型取值进一步限制。根据面的不同,这个元素或属性具有不同的有效值
另一个例子:简单类型category,用于说明书籍的类别
<xsd:simpleType name="category">
<xsd:restriction base="xsd:token">
<xsd:enumeration value="小说"/>
<xsd: enumeration value="散文"/>
<xsd: enumeration value="传记"/>
<xsd: enumeration value="诗歌"/>
<xsd: enumeration value="武侠"/>
<xsd: enumeration value="纪实"/>
</xsd:restriction>
</xsd:simpleType>
利用组合器控制结构
1.sequence组合器:定义了一列元素并且必须按照模式中指定的顺序显示,所有子元素。如果出现的话,都必须按照该顺序出现。
2.choice组合器:用来声明只有一个相容元素必须出现,用于互斥情况,还可以允许任意数量的子元素以任意顺序出现。只要通过把choice组的maxOccurs属性设置为unbounded即可允许子元素以任何顺序出现,出现任意次数。另外,为了指定更加高级的内容,sequence和choice可以彼此嵌套
3.all组合器用来表示符合元素声明的所有元素都应该出现(以任何顺序)且只能出现一次
all组合器与choice和sequence的不同之处
(1) 只能包含元素声明和引用,而不能包含其他组。
(2) 不能出现多次。对于所包含的每个子元素,maxOccurs必须为1,而minOccurs只可以为0或1。不能出现在其他模式组中。all组必须在复杂类型的最高层。