一、Schema的概述
1、schema的含义
XML Scherma是用来描述和约来XML文档的一种XML语言,从功能上看,它和DTD非常类 似,用于定义和描述XML文档的结构和内容模式。
XML Schema定义是一套W3C标准,用于基于XML的称为XML Schema的类型系统。用于定义的语言是一种称为XML模式定义语言的XML语法。Web 服务使用XML作为表示消息和数据的底层格式。
XML文档必须有严格的形式规范,以适应各种具体的应用。首先,XML文档必须符合XML语法限制,术语称为“well-formed XML”其次,为了使XML表示的数据有一定含义,还需要根据应用为其定义语义上的限制,术语称为“validating XML”。
2、DTD存在的缺陷(Scherma的优势)
(I) DTD不是用XML语言编写的,需要不同的分析器技术。
(2) DITD不支持名称空间。
(3) DTD在支持继承和子类方面存在局限性。
(4) DTD没有数据类型的概念,无法对特定元素施加数据类型。
3、Scherna的特征
(1)一致性:利用XML 的基本语法规则来定义其文档结构,从而使XML的模式和实例定义达到了统一;继承了XML的自描述性和可扩展性,使其更具有可读性和灵活性。
(2)完备性:对DTD进行了扩充,引入了数据类型、名称空间。
(3)规范性和准确性:提供了更加规范和完备的机制来约束XML文档,XML Scherma的语义更加准确,可以完成些DTD不能完成的定义,如对元素出现次数的约束等。
(4)面向对象特征:引入了许多成熟的面向对象机制(如继承性和多态性,函数调用声明等)。
(5)扩展性: 允许在事先无法准确描述数据模式的情况下,在XML实例数据中根据需要添加相关的数据。
二、XML Schema的基本结构
XSD是英文XML Schema Definition的缩写,通常也被称为XML Schema。XML Schema文档是扩展名为“.xsd”的一个文本文件,遵循XML的语法规则。W3C规定,一个XML Schema文档的根元素必须是“schema”,名称空间必须是“https://www.w3.org/2001/XMLSchema”。
所有内容都添加在根标记<schema>中,“xsd”是名称空间的前缀,可以任意定义,一般设置为“xsd”或“xs”。在<schema>声明中有两个属性:name属性和xmlns属性。name属性指定schma的名称,可以省略。xmlns属性指定schema文档的名称空间(Namespace)
XSD文档可以定义XML的以下内容:定义可出现在文档中的元素;定义可出现在文档中的属性;定义哪个元素是子元素;定义子元素的次序;定义子元素的数目;定义元素是否为空,或者是否可包含文本;定义元素和属性的数据类型;定义元素和属性的默认值以及固定值。
XML Schema的主要组件
1) 类型
简单类型:不包含任何子元素和属性,只包含文本内容的元素。
复杂类型:包含子元素或属性的元素。
2)元素
<element name="元素名称" type="数据类型" minOccurs="int" maxOccurs="int" />
name属性指明XML元素的名称。
type属性指明XML元素的数据类型,可以选取XML内置的数据类型或用户自定义数据类型。
minOccurs属性指明XML元素的最少出现次数,最小值为0,可选属性。
maxOccurs属性指明XML元素的最多出现次数,最小值为1,最大值为unbounded,表示无限次,是可选属性。
3)属性
注意:只有复杂类型的元素才能拥有属性;元素可以有简单类型或复杂类型,而属性只能有简单类型。
<element name="element_name" type="dataType" />
<xsd:complexType name="dataType">
<xsd:attribute name="attribute_name" type="simple_type" use="use_method"
default="value" fixed="value">
</xsd:attribute>
</xsd:complexType>
element_name指对应XML文件中元素的名称。
attribute_name指属性的名称。
simple_type 指属性的数据类型,可以是内置的数据类型,也可以是由simple type 元素所定义的自定义数据类型。
use_method指明XMD 元素中属性的实际取值要求,可以是optional、required、prohibited。其中,optional 表示该属性值可有可无,是默认值:;required 表示该属性值必须存在,此属性值至少出现一次; prohibited表示该属性值不可出现,用于在restriction元素中限制属性的使用
default 指属性的默认值。
fixed 指如果属性存在,则其内容只能是由本属性指定的值,不可更改。
4)组定义
元素组是把若干元素组成一组。
元素组必须是schema根元素的直接子元素。
若其他类型的元素需将元素组作为子元素时,必须通过引用ref的形式来实现。
5)注释
为了便于阅读和理解XML Schema文档,需要添加注释语句以说明相关内容,XML Schema支持使用<!-- -->注释方式。 此外,还提供了另一个专门的<annotation/>元素来添加注释,具有更好的可读性,还可供其他应用程序读取。
<annotation/>元素含有两个子元素:
<documentation/>: 该元素里主要存放适合阅读的信息。
<appinfo/>: 该元素里主要存放针对其他应用程序的信息。
<annotation/> 元素里可出现任意多个<documentation/>和<appinfo/>子元素,且没有任何顺序要求。
三、XML Schema的数据类型
XML文档元素分为两大类:简单元素和复杂元素。 简单元素:只包含文本的元素,分为XML Schema内置的简单数据类型(44种),自定义的简单数据类型(simpleType)。
元素类型
(1)按照内容的不同分为简单和复杂元素,分别使用simpleType和complexType标示。
简单元素:元素中内容只能是文本,不包含其它的元素和属性。
<?xml version='1.0' encoding='utf-8'?>
<xs:schema xmlns:xs='http://www.nishishui.org/2000/XML Schema' elementFormDefault='qualified' attributeFormDefualt='unqualified'>
<xs:element name='age'>
<xs:simpleType><!-- 使用关键字simpleType声明简单元素 -->
<!--restriction关键字结合minInclusive和maxInclusive控制了XML中元素可接受的值范围为0~100-->
<xs:restriction base="xs:integer">
<xs:minInclusive value='0'/>
<xs:maxInclusive value='100'/>
</xs:restriction>
</xs:simpleType>
</xs:element>
</xs:schema>
复杂元素:元素中包含其它的元素和属性。它有四种类型,分别是空元素、只包含其他元素、只包含正文、包含正文又包含其他元素。
<?xml version='1.0' encoding='utf-8'?>
<xs:schema xmlns:xs='http://www.nishishui.org/2000/XML Schema' elementFormDefault='qualified' attributeFormDefualt='unqualified'>
<xs:element name='age'>
<xs:complexType><!-- 使用关键字complexType声明复杂元素 -->
<!--sequence控制XML内容中元素出现的顺序-->
<xs:sequence>
<!-- 定义具体的元素,这些都是简单元素-->
<xs:element name='firstname' type='xs:string'/>
<xs:element name='lastname' type='xs:string'/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
(2)按照定义位置可分为局部和全局元素。
全局元素:<element>元素的父元素必须是<schema>;
局部元素:局部元素声明只能出现在复杂类型(<complexType>元素)定义内部。即<element>元素的父元素只能是<all>、<choice>或<sequence>元素。
<?xml version='1.0' encoding='utf-8'?>
<xs:schema xmlns:xs='http://www.nishishui.org/2000/XML Schema' elementFormDefault='qualified' attributeFormDefualt='unqualified'>
<xs:element name='用户' type='user'/><!-- 全局元素 -->
<xs:element name='用户名' type='xs:string'/><!-- 全局元素 -->
<xs:element name='密码' type='xs:string'><!-- 全局元素 -->
<xs:complexType name='user'>
<!--sequence控制XML内容中元素出现的顺序-->
<xs:sequence>
<!-- 定义具体的元素,这些都是简单元素-->
<!-- 定义局部元素,使用ref关键字引用,并使用minOccurs和maxOccurs制定元素出现的最少和最多的次数-->
<xs:element ref='用户名' minOccurs='0' maxOccurs='1'/><!-- 局部元素-->
<xs:element ref='密码' minOccurs='0' maxOccurs='1'/><!-- 局部元素-->
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
自定义数据类型的内容模式
</xs:restriction>
<xs:compleType name="">
<xsd:sequence>
子元素模型定义
</xsd:sequence>
<xsd:attribute .../>
</xs:compleType>
XML Schema中的数据类型
类型 | 描述 |
integer | 整数类型 |
string | 字符串类型 |
decimal | 十进制,包含任意精度和位数的数字 |
float | 单精度32位浮点型数字 |
double | 双精度64位浮点型数字 |
Boolean | 布尔类型,值分别为true或false |
date | 日期类型,格式为YYYY-MM-DD |
time | 时间类型,格式为hh:mm:ss |
datetime | 日期时间类型,格式为YYYY-MM-DDThh:mm:ss |
anyURI | 元素中包含一个URI |
1、简单元素的声明
定义简单元素可以通过<element>元素来完成。格式为:
<xsd:element name="元素名称" type="数据类型" />
在DTD中,定义元素的方式为:<!ELEMENT 元素名称 (#PCDATA)>
<ELEMENT>元素的属性名称和作用见下表:
属性名称 | 作用 |
name | 表示元素的名称 |
type | 表示元素内容的类型 |
ref | 表示引用已经定义的元素,不能和type同时使用 |
default | 元素的默认值,可选属性 |
minOccurs | 最少次数,默认值是1 |
maxOccurs | 最大次数,默认值是1 |
2、Schema简单类型声明
XML Schema中,使用<xs: simpleType>元素定义符合用户需要的简单类型元素,为XML文档元素和属性值自定义简单数据类型的语法格式为:
<xs:simpleType >
<xs:restriction base=" xs:数据类型">
<xs:数据类型细节描述value=' value' />
……
</xs:restriction>
</xs: simpleType>
3、自定义数据类型
自定义数据类型是指以一个XMLSchema类型为基础,添加一些限制条件,使用<simpleType>元素。常用的有以下6中类型:
1).限定数值范围
2).限定数值位数
3).限定字符串范围
4).枚举类型
5).列表类型
6).联合类型
4、XML Schema引用
xsi : noNamespaceSchemaLocation表示没有定义目标命名空间,xsd文档是从本地文件。
外联Schema:
<根元素 xmlns:xsi= ...instance xsi:noNamespaceSchemaLocation =" xxx.xsd">
外联DTD :
<!DOCTYPE 根元素 SYSTEM "xxx.dtd">
5、Schema复杂类型声明
顺序问题:Schema提供了all(任意顺序)、sequence(先后顺序)和choice(选择顺序)三种指示符来解决这个问题。
Schema中,<complexType>定义复杂类型元素,语法格式为:
< xsd:element name= "元素名称" type= "数据类型" / >
<xsd:complexType name= "数据类型">
<!--子元素描述部分-->
<xsd:sequence>
......
</xsd:sequence>
</xsd:complexType>
复杂类型元素的子元素列表
cocmplextype元素的子元素 | 定义 |
ALL | 子元素可以无顺序的出现一个或多个 |
SEQUENCE | 子元素必须按顺序出现 |
CHOICE | 子元素选择其中之一出现 |
四、XML Schema的命名空间
W3C颁布的命名空间(NameSpace)标准中对命名空间的定义是: XML命名空间提供了一套简单的方法,将XML文档和URI引用标记的名称相结合,来限定其中的元素和属性名。即命名空间给XML名称添加前缀,使其能够区分所属的领域,从而为元素和属性提供唯一的名称, 其最重要的用途是用于融合不同词汇集的XML文档。
命名空间的声明
1)命名空间一般用xmIns来声明,语法如下:
<元素名 xmlns:prefix="URI">
声明时若前缀名省略,则声明的是缺省的空间,引用缺省命名空间中的元素、属性可不加前缀名。
2)默认的命名空间的声明语法格式为:<元素名 xmlns="URI">
xmIns:命名空间属性名,是声明命名空间必需的属性。
prefix:指明命名空间的前缀名,它的值不能为XML。在引用此命名空间中的名称时,需要在名称前加该前缀名。
五、XML有效性的验证
应用程序会有一些场景需要接受来自不同来源的 XML输入,但如果没有根据正确的模式对其进行验证。 通过接受 XML 文档而不根据文档类型定义 (DTD) 或 XML 模式对其进行验证,如果程序是基于用户只会提供有效输入的假设。那么程序可能会为来自攻击者的意外、不合理或恶意输入敞开了大门。 因为我们在处理这类文件时通常会使用一些开源的解析工具库或者自己实现一些简单解析器,有一定概率在面对恶意来源的文件时出现各种问题,比如之前爆出来的解析器解析循环嵌套文件引起内存溢出。