Web Services 应用开发学习笔记(三):XML模式定义
本文内容:
1. 命名空间
2. Schema概述
3. Schema文档结构
4. Schema数据类型
5. Schema元素声明
6. Schema属性声明
7. 模式重用
1. 命名空间
(1)命名空间是一种将程序库名称封装起来的方法,例如我们在开发.NET程序时,引用的using System.Data等命名空间实际上是使用该空间下的类库资源。
(2)为什么要引用命名空间呢?下面来看两个例子
Table1.xml
<table>
<tr>
<td>水果</td>
<td>苹果</td>
<td>橘子</td>
</tr>
</table>
Table2.xml
<table>
<name>餐桌</name>
<width>100</width>
<height>100</height>
</table>
如果我们将上面两个XML文档中该代码部分合并在一起使用的话,由于都包含了<table>元素,并且它们的含义都不一样,命名空间就会发生冲突,因此我们需要引入命名空间来区分它们。下面来看引入后的两个例子
Table1.xml
<fruit:table>
< fruit:tr>
< fruit:td>水果</ fruit:td>
< fruit:td>苹果</ fruit:td>
< fruit:td>橘子</ fruit:td>
</fruit:tr>
</table>
Table2.xml
<furniture:table>
< furniture:name>餐桌</ furniture:name>
< furniture:width>100</ furniture:width>
< furniture:height>100</ furniture:height>
</ furniture:table>
<table>元素在两个文档中分别是<fruit:table>和<furniture:table>,所以当两个文档的代码合并在一起时就不会发生命名冲突。
(3)创建命名空间
先来看来个术语:
URI:Uniform Resource Identifier,统一资源标识符。
URL:Uniform Resource Location,统一资源定位符。
我们可以这样理解,XML命名空间本身就是一个URI,是可以辨别的标识符,和URL组合在一起来区别这些名称相同的标识。例如:http://www.cnblogs.com/cate/aspnet/ http://www.cnblogs.com/cate/csharp/ URL是指http://www.cnblogs.com/这一部分,而cate/aspnet/和cate/csharp/就是指不同的命名空间,又叫不同的资源标识符。
语法结构:xmlns:prefix=”URI”
语法解析:命名空间需要在XML文档开头部分声明,一般放在元素的开始标记(即根元素)。其中,pre为定义的命名空间的前缀,命名可以任意字符,可以将命名空间分为默认的和明确的。URI是为当前命名空间选择的网址。用来标识命名空间的URI并不会被XML解析器调用,作用是仅仅给命名空间一个唯一的名字,也就是说,设置URI并不是指这个标识真的要到那个网址去读取,仅仅作为一种区别的标志而已。使用者可以分配任何名称或字符串作为一个URI。
a.默认声明
默认的命名空间,不需要指定前缀,而使用该命名空间的所有元素和属性不需要任何前缀。例子:
<table xmlns=” http://www.cnblogs.com/cate/aspnet/”>
<tr>
<td>水果</td>
<td>苹果</td>
<td>橘子</td>
</tr>
</table>
b.明确声明
xmlns关键字与一个命名空间URI的前缀想关联,当在根元素处使用命名空间时,该元素所有的子元素都将通过一个前缀与同一命名空间相关联。例子:
<?xml version=”1.0” encoding=”UTF-8”?>
<fruit:table xmlns:fruit=” http://www.cnblogs.com/cate/aspnet/”>
< fruit :tr>
< fruit :td>水果</ fruit :td>
< fruit :td>苹果</ fruit :td>
< fruit :td>橘子</ fruit :td>
</ fruit :tr>
</ fruit :table>
2. Schema概述
XML Schema 是Mircosoft开发的一种定义XML文档的模式,称为XML模式定义语言——XML Schema Definition,简称XSD。可以定义XML文档中的元素和属性的数据类型。DTD也是有这一功能,那为什么还要引入XSD呢?
因为DTD存在缺陷,所以需要一个强大的模式去支持XML,缺点如下:
(1)DTD基于正则表达式的,描叙能力有限。
(2)DTD没有数据类型的支持,在大多数应用环境下能力不足。
(3)DTD约束能力较弱,无法对XML实例文档做出更细致的语义限制
(4)DTD不够结构化,重用的代价相对较高。
(5)DTD不支持命名空间
使用XML Schema的优点如下:
(1) XML Schema的语法完全遵循XML的语法规范。
(2) XML Schema支持数据类型(整型、浮点型、布尔型等)。
(3) XML Schema内容模型是开放的,可以随意扩充
(4) XML Schema支持属性组
(5) XML Schema支持综合命名空间
下面来看Schema和DTD对比例子
Note.xml
<?xml version=”1.0” encoding=”UTF-8”?>
<!—引用DTD-->
<!DOCTYPE note System “note.dtd”>
<note>
<to> cnblogs </to>
<from> TerryChan </from>
<heading>WebSerivce</heading>
<body> XML模式定义</body>
</note>
<?xml version=”1.0” encoding=”UTF-8”?>
<!—引用XSD-->
<note xmlns=” http://www.cnblogs.com/ForEvErNoME/”
xmlns:xsi=” http://www.cnblogs.com/ForEvErNoME/ XMLSchema”
xsi:schemaLocation=” http://www.cnblogs.com/ForEvErNoME/Note.xsd”>
<to> cnblogs </to>
<from> TerryChan </from>
<heading>WebSerivce</heading>
<body> XML模式定义</body>
</note>
Note.dtd
<!ELEMENT note(to,from,heading,body)>
<!ELEMENT to (#PCDATA)>
<!ELEMENT from (#PCDATA)>
<!ELEMENT heading (#PCDATA)>
<!ELEMENT body (#PCDATA)>
Note.xsd
<?xml version=”1.0” encoding=”UTF-8”?>
<xs:schema xmlns:xs=” http://www.cnblogs.com/ForEvErNoME/ XMLSchema”
targetNamespace=” http://www.cnblogs.com/ForEvErNoME/”
xmlns=” http://www.cnblogs.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>
上述代码中, xmlns=” http://www.cnblogs.com/ForEvErNoME/”规定了默认命名空间的声明,此声明会告知Schema验证器,在此XML文档中使用的所有元素都被声明与该命名空间;xmlns:xsi=” http://www.cnblogs.com/ForEvErNoME/ XMLSchema”声明了可用的XM,L Schema实例命名空间;schemaLocation属性定义了两个值:第一个是需要使用的命名空间,第二个值是提供命名空间使用的XML Schema的位置
3. Schema文档结构
XMLSchema文档实际上只是XML文档的另外一个应用。
语法结构:
<?xml version=”1.0” encoding=”UTF-8”?>
<xs:schema xmlns:xs=” http://www.cnblogs.com/ForEvErNoME/ XMLSchema”
targetNamespace=” http://www.cnblogs.com/ForEvErNoME/”
xmlns=” http://www.cnblogs.com”
elementFormDefault=”qualified”>
<!—Schema文档中子元素的名字和类型的定义-->
</xs:schema>
语法解析:
所有Schema文档都必须要使用schema作为其根元素。
第2行代码指出该Schema文档中用到的元素和数据类型来自命名空间http://www.cnblogs.com/ForEvErNoME/ XMLSchema,前缀为xs。
第3行代码指出该Schema文档中定义的元素使用命名空间http://www.cnblogs.com/ForEvErNoME/。
第4行代码指出默认的命名空间http://www.cnblogs.com。当第二行代码中明确声明的空间找不到,就会自动使用默认的命名空间。
第5行代码指出任何XML实例文档所使用的且在此Schema中声明过的元素必须被命名空间限定
4. Schema数据类型
XML Schema中的数据类型可以分为简单类型和复合类型,其中简单类型是不能分割的原子类型;复合类型类似于编程语言中的自定义类型,它是由已存在的简单类型组合而成的。
(1) 简单类型
XML Schema规范中定义了两类简单类型:内置类型和用户定义类型。
a. XML Schema中内置的数据类型
数据类型 |
描述 |
示例 |
string |
XML中任何的合法字符 |
TerryChan |
boolean |
逻辑判断,true或false |
1和0或true和false |
date |
表示CCYY-MM-DD格式的日期 |
2012-03-01 |
float |
32位精确度的浮点实数 |
123,.456 |
……等 |
|
|
b.XML Schema用户自定义类型
用<xs:sinpleType>元素定义
语法结构:
<xs:simpleType name=”自定义数据类型的名称”>
<xs:restriction base=”所基于的内置数据类型的名称”>
自定义数据类型的内容模式
</xs:restriction>
</xs:simpleType>
Restriction(限制)用于XML元素或者属性定义可接受的值,restriction元素的常用子元素
元素名称 |
描述 |
enumeration |
在指定的数据集中选择,限定用户的选值 |
fractionDigits |
限定最大的小数位,用于控制精度 |
length |
指定数据的长度 |
maxExclusive |
指定数据的最大值(小于) |
maxInclusive |
指定数据的最大值(小于等于) |
maxLength |
指定长度的最大值 |
minExclusive |
指定数据的最小值(大于) |
minInclusive |
指定数据的最小值(大于等于) |
minLength |
指定最小长度 |
pattern |
指定限制数据的正则表达式 |
例如电话号码的标签格式为:<phone>0202-77778888</phone>,此标签中的内容要求只能容纳13个字符长的字符串值,并且匹配模式dddd-dddddddd(d表示0~9之间的数字),即phone元素的自定义数据类型如下:
<xs:simplyType name=”phone”>
<xs:restriction base=”xs:string”>
<xs:length value=”13”/>
<xs:pattern value=”\d{4}-\d{8}”/>
</xs: restriction>
</xs:phone>
(2) 复合类型
复合类型是指包含其他子元素、属性或混合内容的元素。为了声明复合元素,应当首先定义一个复合数据类型(complexType)。然后通过使用该数据类型与元素相关联来声明一个复合元素。
语法结构:
<xs:complexType name=”数据类型名称”>
<!—内容模型定义(包括子元素和属性的声明)-->
</xs:complexType>
例子
Note.xsd
<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:complexType>
在xml模式中,可以将相关联的元素组合为组。Schema提供了能够用来组合用户定义的元素,常用的元素有以下几个:
sequence:指定组中的子元素按照一定顺序出现。
group:用通用明组合成组。
choice:只能使用组中的子元素之一。
all:组中的子元素在父元素内可以按照任意顺序出现。
5. Schema元素声明
Schema中的元素声明分为简单元素和复合元素。
(1) 简单元素:一个元素中如果仅仅包含数字、字符串或其他数据,不包括子元素和属性,这种元素称为简单元素。
语法结构:
<xs:element name=”元素名称”
type=”数据类型”
default=”默认值”
minOccurs=”nonNegativeInterger”
maxOccurs=”nonNegativeInterger|unbounded”/>
语法解析:
name指定要声明元素的名称。
default指定该元素默认值,此项可选。
Type指定该元素的数据类型。
minOccurs指定该元素在XML文档中可以出现的最小次数,此项可选。
maxOccurs指定该元素在XML文档中可以出现的最大次数,此项可选。
例子:
Student.xml
<?xml version=”1.0” encoding=”UTF-8”?>
<student xmlns:xsi:=” http://www.cnblogs.com/ForEvErNoME/ XMLSchema”
<xsi:noNamespaceSchemaLocation=”Student.xsd”>
<name>TerryChan</name>
<sex>male</sex>
<age>22</age>
<phoneno>88889999</phoneno>
此文档中的元素name、sex、age和phoneno的取值须满足下列条件
元素name、sex、age和phoneno是简单类型的元素。
name、sex的值必须是字符串。
age元素的值必须是大于0的整数。
phoneno元素的值必须是8位的数字字符串。
Student.xsd
<xs:element name=”name” type=”xs:string”/>
<xs:element name=”sex” type=”xs:string”/>
<xs:element name=”age” type=”xs:positoveInteger”/>
<xs:element name=”phoneno” >
<xs:simpleType>
<xs:restriction base=”xs:string”>
<xs:length value=”8”/>
<xs:legth value=”\d{8}”/>
</xs:restriction>
</xs:simpleType>
</xs:element>
(2) 复合元素:包含内容、属性和子元素的元素。
语法结构:
<xs:element name=”元素名称”
type=”复合数据类型”
default=”默认值”
minOccurs=”nonNegativeInterger”
maxOccurs=”nonNegativeInterger|unbounded”/>
复合元素的声明方式与简单元素的声明方式类似,不同的是type属性的值必须通过外部引用一个复合数据类型。
例子:
Student.xml
<?xml version=”1.0” encoding=”UTF-8”?>
<student xmlns:xsi:=” http://www.cnblogs.com/ForEvErNoME/ XMLSchema”
<xsi:noNamespaceSchemaLocation=”Student.xsd”>
<name>TerryChan</name>
<sex>male</sex>
<age>22</age>
<phoneno>88889999</phoneno>
此文档中的元素name、sex、age和phoneno的取值须满足下列条件
元素name、sex、age和phoneno是简单类型的元素。
name、sex的值必须是字符串。
age元素的值必须是处于16和30之间的整数
phoneno元素的值必须是8位或11位的数字字符串。
Student.xsd
<?xml version=”1.0” encoding=”UTF-8”?>
<xs:schema xmlns:xs=” http://www.cnblogs.com/ForEvErNoME/ XMLSchema”>
<xs:element name=”student” type=”studentDef”/>
<!—定义复合类型-->
<xs:complexType name=”studentDef”>
<xs:sequence>
<xs:element name=”name” type=”xs:string”/>
<xs:element name=”sex” type=”sexDef”/>
<xs:element name=”age” type=”ageDef”/>
<xs:element name=” phoneno” type=”phonenoDef”/>
</xs:sequence>
</xs:complexType>
<!—定义age类型-->
<xs:simpleType name=”ageDef”>
<xs:restriction base=”xs:positiveInterger”>
<xs:minInclusive value=”16”/>
<xs:minInclusive value=”30”/>
</xs: restriction >
</ xs:simpleType>
<!—定义sex类型-->
<xs:simpleType name=” sexDef”>
<xs:restriction base=”xs:string”>
<xs:enumeration value=”male”/>
<xs:enumeration value=”female”/>
</xs: restriction >
</ xs:simpleType>
<!—定义phoneno类型-->
<xs:simpleType name=” phonenoDef”>
<xs:restriction base=”xs: string”>
<xs:pattern value=”\d{8}|\d{11}”/>
</xs: restriction >
</xs:simpleType>
</xs:schema>
6. Schema属性声明
属性声明用于命名属性并制定属性值得类型。在Schema中,使用attribute标记,只能是简单类型,只能包含文本,且没有子属性。
语法结构:
<attribute name=”属性”
default=”默认值”
fixed=”固定值”
type=”数据类型”
use=”optional|required”/>
语法解析:
Name用来指定自定义属性名称。
Default用来指定自定义属性的一个默认值。
Fixed用来为自定义属性提供一个固定值。
Type指定该属性的数据类型,此处只能是简单数据类型。
Use指定该属性值是optional(可选,默认属性)还是required(强制)。
例子
<xs:attribute name=”age” type=”xs:integer”/>
7. 模式重用
XML Schema支持高度冲永兴,即:在一个模式中声明的组件能够被另外一个模式重用。可以通过使用include元素和import元素来实现模式的重用。
(1) include元素
用来包含或引用一个明确地址的外部模式
语法结构:
<include id=”ID” schemaLocation=”filename”/>
语法解析:
Id用来指定元素的ID,ID必须是唯一的。该项可选。
schemaLocation指定模式文件的物理地址。
例子:
<?xml version=”1.0” encoding=”UTF-8”?>
<xs:schema xmlns:xs=” http://www.cnblogs.com/ForEvErNoME/ XMLSchema”
targetNamespace=” http://www.cnblogs.com/ForEvErNoME/”
xmlns=” http://www.cnblogs.com”
<xs:include schemaLocation=” http://www.cnblogs.com/ForEvErNoME/1.xsd”/>
<xs:include schemaLocation=” http://www.cnblogs.com/ForEvErNoME/2.xsd”/>
<!—Schema文档中子元素的名字和类型的定义-->
</xs:schema>
(2) import元素
import和include有同样的功能,但是import允许访问来自多个不同目标名称空间的模式的组件。
语法结构:
<import id=”ID” namespace=”namespace” schemaLocation=”filename”/>
语法解析:
Id用来指定元素的ID,ID必须是唯一的。该项可选。
Namespace指定被引入模式所属的命名空间URI,它指定前缀。该前缀用来使一个元素或属性和一个特定的命名空间相关联。
schemaLocation指定模式文件的物理地址。