第 3 章 XML 模式语言 ( XML Schema )

Preview:

DESCRIPTION

第 3 章 XML 模式语言 ( XML Schema ). DTD 的缺点 : (1) 缺少数据类型和命名空间的支持 ; (2) 语法规则过于简单以至描述能力有限 ; (3) 使用非 XML 的格式等。 XML Schema 是专用于 XML 的模式语言,功能更强大 , 且本身即为 XML 格式。. 3.1 XML 模式语言. XML 模式语言是指用来描述 XML 结构、数据内容、相关约束等方面特征的语言。 XML 模式语言的种类很多: ISO Schematron - PowerPoint PPT Presentation

Citation preview

第 3 章 XML 模式语言 ( XML Schema )

DTD 的缺点 : (1) 缺少数据类型和命名空间的支持 ; (2) 语法规则过于简单以至描述能力有限 ; (3) 使用非 XML 的格式等。 XML Schema 是专用于 XML 的模式语言,功

能更强大 , 且本身即为 XML 格式。

3.1 XML 模式语言 XML 模式语言是指用来描述 XML 结构、数

据内容、相关约束等方面特征的语言。 XML 模式语言的种类很多:

ISO Schematron XDR (XML-DATA Reduced) XML Schema RELAX NG

一 种 非 常 独 特 的 XML 模 式 语

言 , 无 论 是 结 合 其 他 模 式 语 言

或 者 单 独 使 用 都 具 有 强 大 的 功

能 。 Schematron 语 言 允 许 直

接 表 达 规 则 , 而 不 需 要 创 建 完

整 的 语 法 基 础 设 施 。

是 由 Microsoft 公 司 提 出 的 XML 简

化 模 式 语 言 , 作 为 W3C 在 讨 论 XML Schema 工 作 草 案 过 程 中 提 出 的 一 种

过 渡 性 Schema 语 言 , XDR 已 经 被

业 界 普 遍 认 可 , 得 到 许 多 产 品 ( 例 如 ,

MS-BiztalkServer 、 MS-SQLServer 、

MS-Office ) 的 广 泛 支 持 。

W3C 的 正 式 推 荐 标 准 , 提 供

了 XML 模 式 声 明 的 完 整 语 法 、

丰 富 的 数 据 结 构 等 , 目 前 已 成

为 应 用 最 广 泛 的 XML 模 式 语

言 。一 种 基 于 语 法 的 XML 模 式 语 言 , 可

用 于 描 述 、 定 义 和 限 制 XML 词 汇 表 。

它 以 简 洁 性 和 表 达 能 力 著 称 , 并 且 具 有

良 好 的 可 扩 展 性 。

XML Schema 的特征 1 与 DTD 相比, XML Schema 具有特征:

一致性: XMLSchema 利用 XML 的基本语法规则来定义其文档结构,从而使 XML 的模式和实例定义达到统一;继承了 XML 的自描述性和可扩展性,使其更具有可读性和灵活性。

完备性: XML Schema 对 DTD 进行了扩充,引入了数据类型、命名空间,并且支持对其他 XML Schema 的引用,从而使其具备较强的模块性;

规范性和准确性: XML Schema 提供了更加规范和完备的机制来约束 XML 文档。 XML Schema 的语义更加准确,可以完成一些 DTD 不能完成的定义,如对元素出现次数的约束等。

XML Schema 的特征 2

面向对象特征: XML Schema 中引入了许多成熟的面向对象机制(比如继承性和多态性),使得数据模式在应用中更加灵活。

扩展性: DTD 所描述的文档结构是非常严格的( closed ),没有显式声明的内容绝不允许在 XML 实例数据中出现;而 XML Schema 则提供了一些扩展机制( open ),允许在事先无法准确描述数据模式的情况下,在 XML 实例数据中根据需要添加相关的数据。

3.1.2 XML Schema 的一个简单示例

student.xsd XML Schema 文件的后

缀名通常为 .xsd XML Schema 文件是一

个特殊的 XML 文件。 注意根元素及命名空间。

实例 XML 文档

<?xml version="1.0" encoding="UTF-8"?><student>

<name>XiaoWang</name><gender> 男 </gender><no>123</no><telephone>010-12345678</telephone><gpa>80</gpa>

</student> <?xml version="1.0" encoding="UTF-8"?><student xsi:noNamespaceSchemaLocation="student.xsd"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance

">......

</student>

XML Schema 中的“注释”元素

在 W3C XML Schema 文件中,推荐使用 xsd:annotation 元素来增加注释内容, xsd:annotation 元素可以包含两个子元素 xs:appinfo 和 xs:documentation 。

前者用于表示计算机应用程序处理的注释,而后者则表示供开发人员阅读的注释。

这两个子元素是 W3C XML Schema 中唯一的混合内容模型的元素,其中可以包含任何文本和子元素。

3.2 XML Schema 中的数据类型

元素是其中最为重要的组成部分,一个 XML 文档中可能不包含任何属性或者文本数据,但是必须包含元素(至少包含一个根元素)。

XML Schema 中的数据类型实际上主要是针对 XML 元素而言的,换句话说,是针对各种元素的内容及其结构的。

<product pid="1345"/> <food type="dessert">Ice cream</food>

<lastname> Jack </lastname><description/>

元素的类型

在 W3C 的 XML Schema 规范中,将元素分为两类: 简单类型:不包含任何子元素和属性的元素。换句

话说,简单类型的元素只能包含文本内容,或者为不包含属性的空元素(文本内容为空)。

复杂类型:包含子元素和 / 或属性的元素(其中属

性的声明包含在元素的复杂类型定义中)。

有关元素类型的说明

简单类型元素只能包含文本内容,而复杂类型元素除了包含子元素和 / 或属性之外,也可以包含文本内容。

“ 文本内容”并不是指的字符串数据类型,在 XML Schema 规范中定义了 44 种简单数据类型 ,“文本内容”可以是这些简单数据类型中的任何一种(甚至还可以是派生的简单数据类型)。

比如:<xsd:element name=“orderid” type=“xsd:integer”/> 。<orderid>1032</orderid> 正确<orderid>abc</orderid> 错误

• anySimpleType 是所有简单数据类型的基础类型。 • anySimpleType 也是一种实际的、可用的数据类型,它是所有简单数据类型的根节点,与 anyType 不同的是,它只能表示标量数据。 • 比如:<element name="Currency" type="anySimpleType" />

<Currency> USD </Currency> <Currency><dollars>100</dollars></Currency>

• anyType 是 XML Schema 中所有数据类型(包括简单类型和复杂类型、内置数据类型和用户定义数据类型)的基础类型,如果拿 Java 语言来做个类比,那么 xsd:anyType 类似于 Java 中的 java.lang.Object 。• anyType 分为“简单类型”和“复杂类型”。• anyType 是一种实际的、可用的数据类型,而不仅仅只是在 XML Schema 数据类型层次结构中作为抽象的根节点。 比如:<element name="Currency" type="anyType" />

<Currency> USD </Currency> <Currency><dollars>100</dollars></Currency>

3.2.1 XML Schema 的内置数据类型

• 内置基本数据类型( Primitive Datatype ):这些类型是独立存在的,而不是在其他数据类型的基础上定义的。比如数学上的十进制数,定义为 decimal 。• 在 XML Schema 规范中,一共定义了 19 中内置的基本数据类型,它们可以单独使用、或者作为其他派生数据类型(包括内置派生数据类型和用户派生数据类型)的基础类型。

• 内置派生数据类型( Derived Datatype ):这些内置类型的定义依赖于其他的数据类型(即内置基本数据类型)。• 比如 decimal 和 nonNegativeInteger ,可以将后者理解为满足某种条件(非负整数)的 decimal ,实际上, decimal 是 XML Schema 中所有十进制数值类型的基础类型。

常用数据类型(字符串类型)字符串类型

string string 数据类型的取值可以是任意字符串,其中可以包含空格、 LF 、CR 和制表符等空白字符。对于 string 数据类型, XML 解析器将不会修改其内容。

normalizedString

normalizedString 数据类型派生于 string 数据类型。 normalizedString 数据类型的值可以包含任意字符,但是 XML 解析器将删除其中的 LF 、 CR 和制表符等空白字符;换句话说, normalizedString 数据类型是不包含上述特殊字符的字符串。

token token 数据类型也是 string 数据类型的派生类型,其中可以包含任意字符,但是 XML 解析器将删除其中的 LF 、 CR 和制表符等空白字符、开头和结尾的空格、以及连续的空格。

language 包含合法语言 id 的字符串。Name 包含合法 XML 名称的字符串,可以包含命名空间前缀。NCName 包含合法 XML 名称的字符串,不可以包含命名空间前缀。ID 、 IDREFS 、NMTOKEN 等

这些数据类型来自于 DTD ,在 XML Schema 中保留了这些数据类型,并且与 DTD 中的使用方式相 同,这些类型只能用于元素的属性。

... ...

常用数据类型(数值类型 )数值类型

float IEEE 的单精度 32 位浮点数。

decimal 可以使用十进制数字表示的实数。

integer 派生于 decimal ,限制条件是十进制整数。

long 派生于 integer ,限制条件是最大值为 9223372036854775807 、最小值为 -9223372036854775808 。

int 派生于 long ,限制条件是最大值为 2147483647 、 最小值为 -2147483648 。

nonPositiveInteger 派生于 integer ,限制条件是最大值为 0 。

... ...

常用数据类型(日期、时间和其他类型 )日期、时间类型 

date 用于指定一个日期,具体格式为: YYYY-MM-DD ,其中: YYYY 表示年;MM 表示月; DD 表示日。假如 <xsd:element name="start" type="xsd:date"/>,那么该元素可以为 <start>2002-09-24</start>。

time 用于指定一个时间,具体格式为: hh:mm:ss ,其中: hh 表示时; mm 表示分; ss 表示秒。假如 <xsd:element name="start" type="xsd:time"/>,那么该元素可以为 <start>09:00:00</start>。

datetime 用于指定一个日期和时间,具体格式为: YYYY-MM-DDThh:mm:ss 。假如 <xsd:element name="startdate" type="xsd:datetime"/>,那么该元素可以为 <startdate>2002-05-30T09:00:00</startdate>。

duration 指定一个时间间隔,具体格式为: PnYnMnDTnHnMnS ,其中: P 表示时间间隔(必需的); nY 表示年数; nM 表示月数;依次类推。

其他类型boolean 用于指定 true 或者 false 。合法的取值包括: true 、 false 、 1(表

示 true )、 0(表示 false )。base64Binary、hexBinary

用于表示二进制格式的数据, base64Binary 表示 Base64 编码的二进制数据, hexBinary 表示十六进制编码的二进制数据。

anyURI 用于表示一个 URI ,如果其中包括空格,必须使用 %20 进行替换。

3.2.2 XML Schema 中的派生简单数据类型 仅使用 44种基本数据类型仍然是不够的。比

如,假设希望定义一个 email 数据类型、或者 telephone 数据类型,用于约束合法的 email 和 telephone 数据,那又该怎么做呢?

XML Schema 为此提供了自定义简单数据类型、复杂数据类型的机制,以便用户在需要的时候对 XML Schema 类型系统进行扩充。

可以通过几种不同的方法(通过限制、列表、或者组合)自定义简单数据类型。

1. 通过限制( restriction)派生简单数据类型 通过限制的方式派生简单数据类型的语法格式

如下所示,下面的两种形式分别声明了一个无名的、以及一个命名的(名为 SimpleTypeName )简单数据类型:

<xsd:simpleType> <xsd:restriction base="BaseType"> ... facets descriptions ... </xsd:restriction> </xsd:simpleType>或者:<xsd:simpleType name="SimpleTypeNam

e"> <xsd:restriction base="BaseType"> ... facets descriptions ... </xsd:restriction> </xsd:simpleType>

a). 通过设置最大值或最 小值,对数值类型取值的范围进行限制

<xsd:element name="MyIntegerElement" type="MyInteger"/><xsd:simpleType name="MyInteger"> <xsd:restriction base="xsd:integer"> <xsd:minInclusive value="0"/> <xsd:maxInclusive value="100"/> </xsd:restriction></xsd:simpleType> <xsd:element name="MyIntegerElement">

<xsd:simpleType> <xsd:restriction base="xsd:integer"> <xsd:minInclusive value="0"/> <xsd:maxInclusive value="100"/> </xsd:restriction> </xsd:simpleType> </xsd:element>

与 minInclusive 和 maxInclusive 相对应,还有 minExclusive 和 maxExclusive ,后面两种限制方面的取值空间为开区间。

b). 通过枚举,将取值空间限制为一组合法的取值

<xsd:simpleType> <xsd:restriction base="xsd:string"> <xsd:enumeration value="Audi"/> <xsd:enumeration value="Golf"/> <xsd:enumeration value="BMW"/> </xsd:restriction> </xsd:simpleType>

这个数据类型的基本类型是 xsd:string,在此基础上,通过 xsd:enumeration 列举出了若干个合法的取值。

c). 通过给定一 个正则表达式,限制字符串内容的模式

<xsd:simpleType> <xsd:restriction base="xsd:string"> <xsd:pattern value="[a-z]"/> </xsd:restriction> </xsd:simpleType>

<xsd:simpleType name="Telephone"> <xsd:restriction base="xsd:string"> <xsd:pattern value="(\d{4}-\d{8})|(\d{3}-\d{8})|(\d{4}-\d{7})"/> </xsd:restriction></xsd:simpleType>

正则表达式中的各种元符号( metacharacter )及其描述 1

符号表示

描述 简单示例

\ 转义字符。 比如 \n 表示换行 \x0a , \f 表示换页符号 \0x0c , \t 表示制表符 \x09 , \r 表示回车 \x0d , \\

表示 \ 。^ 表示行首。 比如 ^Hello 表示匹配行首、而不是任意的 Hell

o 。$ 表示行尾。 比如 done$ 表示匹配行尾、而不是任意的 done 。* 表示前面的符号或子表达式匹

配 0 次或多次。 比如 zo* 可以匹配 "z" 和 "zoo" 。 * 等价于下

面介绍的 {0,} 。+ 表示前面的符号或子表达式匹

配 1 次或多次。 比如 zo+ 可以匹配 "zo" 和 "zoo" ,但是不能

匹配 "z" 。 + 等价于下面介绍的 {1,} 。? 表示前面的符号或子表达式匹

配 0 次或 1 次。 比如 do(es)? 可以匹配单词 "do" 中的 "do" 或

者单词 "does" 。 ? 等价于下面介绍的 {0,1} 。{n}{n,}{n,m}

n 和 m 都是非负的整数(分别为上下限),表示前面的符号或子表达式匹配指定次数。

比如 o{2} 表示两个连续的 o (如 "food" )。 比如 o{2,} 表示两个以上的 o (如 "fooood" )

。 比如 o{1,3} 表示一到三个 o (如 "fod" 、 "foo

d" )

正则表达式中的各种元符号( metacharacter )及其描述 2

符号表示 描述 简单示例. 匹配除 "\n" 之外的所有单个符号。 比如 f.*d 表示一行中包含字符 f 和 d 的内容(无论它们之间

是什么内容),如 "friend" 。x|y 匹配 x 或 y 。 比如 z|food 匹配 "z" 或 "food" ,而 '(z|f)ood' 匹配 "zood"

或 "food" 。括号用于改变运算优先级。[xyz] 一个字符集合。表示匹配集合中的

任何一个符号。[abc] 可以匹配 a 、 b 、 c 中的任何一个。

[^xyz] 字符集合的补集。 [^abc] 可以匹配 a 、 b 、 c 以外的字符。[a-z] 字符范围。 [a-z] 可以匹配任何 'a' 到 'z' 之间的小写字符。

[^a-z] 字符范围的补集。 [^a-z] 可以匹配任何非小写的字符。\b\B

匹配单词边界。匹配非单词边界。

'er\b' 可以匹配 "never" 中的 'er' ,但不能匹配 "verb" 中的 'er' 。

'er\B' 可以匹配 "verb" 中的 'er' ,但不能匹配 "never" 中的 'er' 。

\d \D

匹配一个数字字符。匹配一个非数字的字符。

等价于 [0-9] 。 等价于 [^0-9] 。

\s\S

匹配任何空白字符。匹配任何非空白字符的字符。

等价于 [\n\r\t\0x20] (空白字符共有四种)。 等价于 [^\n\r\t\0x20] 。

\w\W

匹配任何单词符号,包括下划线。匹配任何非单词符号。

等价于 [A-Za-z0-9_ ] 。 等价于 [^A-Za-z0-9_ ] 。

正则表达式的使用 比如我们希望建立一个 email 数据类型,以便验证在

用户提交的 XML 文档中,指定的元素中包含合法的电子邮件地址:

很多文本编辑器(如 EditPlus 、 Word )中进行内容查找时,可以使用正则表达式作为条件。另外 Java 语言中提供了 java.util.regex ,其中包含 Matcher 和 Pattern 两个类、以及其他的接口等,借助正则表达式的强大功能,从而极大地增强了面向对象的 Java 语言的文本处理能力。

([a-zA-Z0-9_\-\.]+)@([a-zA-Z0-9_\-\.]+)\.([a-zA-Z]{2,5}) somthing@someserver.comfirstname.lastname@mailserver.domain.com somename@server.domain-com

可以 参考网站 http://regexlib.com

d). 限制文本内容中字符串的 长度

可以使用 length 、 maxLength 和 minLength 等 Schema 元素来限制文本内容的长度。<xsd:simpleType> <xsd:restriction base="xsd:string"> <xsd:length value="8"/> </xsd:restriction> </xsd:simpleType> <xsd:simpleType>

<xsd:restriction base="xsd:string"> <xsd:minLength value="5"/> <xsd:maxLength value="8"/> </xsd:restriction> </xsd:simpleType>

e). 限制文本内容中数值的 位数和小数位数

可以使用 totalDigits 和 fractionDigits 来限制数值的总位数和小数位数。

<xsd:simpleType> <xsd:restriction base="xsd:decimal"> <xsd:totalDigits value="4"/> <xsd:fractionDigits value="2"/> </xsd:restriction></xsd:simpleType>

XML Schema 中的各种限制方面 Facet

方面 描述enumeration 定义一组合法的取值。fractionDigits 指定最大的小数位数,必须大于或等于零。length 指定字符串中字符或列表数据类型中项的数目,必须大于或等于零。maxExclusive 指定数值类型值的上限(取值必须小于这个上限)。maxInclusive 指定数值类型值的上限(取值必须小于或等于这个上限)。maxLength 指定字符串中字符或列表数据类型中项的最大数目,必须大于或等于零。minExclusive 指定数值类型值的下限(取值必须大于这个下限)。minInclusive 指定数值类型值的下限(取值必须大于或等于这个下限)。minLength 指定字符串中字符或列表数据类型中项的最小数目,必须大于或等于零。

pattern 指定一个正则表达式,描述合法的字符序列。totalDigits 指定最大的位数,必须大于或等于零。whiteSpace 指定如何处理空白字符( CR 、 LF 、 Space 和 Tab )。

有关通过限制派生简单数据类型的 几项说明

①. 在通过限制派生简单数据类型时,必须注意取值空间的有效性。

<xsd:simpleType> <xsd:restriction base="xsd:int"> <xsd:totalDigits value="1"/> <xsd:minInclusive value="10"/> <xsd:maxInclusive value="100"/> </xsd:restriction></xsd:simpleType>

②. 对于所有的限制方面,不允许在进行限制的同时扩大基本数据类型的值空间。

<xsd:simpleType name="minInclusive"> <xsd:restriction base="xsd:float"> <xsd:minInclusive value="10"/> </xsd:restriction> </xsd:simpleType>

<xsd:simpleType name="minInclusive2"> <xsd:restriction base="minInclusive"> <xsd:minInclusive value="0"/> </xsd:restriction></xsd:simpleType>

2.通过列表( List)派生简单数据类型 仅有前面介绍的简单类型仍然不够,假设我们希望在某个元素的内容中包含由若干个整数值组成的文本,比如:

通过列表进行派生,实际上就是在定义列表中每个项目的具体类型的基础上,允许多个项目构成一个列表(其中使用空格进行分隔)。

<MyIntegers>100 101 102</MyIntegers>

通过列表进行派生 1

<xsd:simpleType name="integerList"> <xsd:list itemType="xsd:integer"/></xsd:simpleType>

<xsd:simpleType name="myIntegerList"> <xsd:list> <xsd:simpleType> <xsd:restriction base="xsd:integer"> <xsd:minInclusive value="100"/> </xsd:restriction> </xsd:simpleType> </xsd:list></xsd:simpleType>

通过列表进行派生 2<xsd:simpleType name="integerGE100"> <xsd:restriction base="xsd:integer"> <xsd:minInclusive value="100"/> </xsd:restriction></xsd:simpleType><xsd:simpleType name="myIntegerList"> <xsd:list itemType="integerGE100"/></xsd:simpleType>

<xsd:simpleType name="myIntegerList"> <xsd:list> <xsd:simpleType> <xsd:restriction base="xsd:integer"> <xsd:minInclusive value="100"/> </xsd:restriction> </xsd:simpleType> </xsd:list></xsd:simpleType><xsd:simpleType name="FourIntegerList"> <xsd:restriction base="myIntegerList"> <xsd:length value="4"/> </xsd:restriction></xsd:simpleType>

3. 通过合并 (Union)派生简单数据类型

通过列表派生简单数据类型,使得我们可以在文本内容中加入多个项目(比如多个整数值),但是无论有多少个项目,它们的数据类型必须一致,这是通过列表方式派生简单数据类型的基本要求。

假设在一个 student 元素中存放学生各门功课(语、数、外三门)的成绩:

<student1>70 80 90</student1>

<student2>70 80 N/A</student2>

通过合并 进行派生<xsd:simpleType name="integerOrDate"> <xsd:union memberTypes="xsd:integer xsd:date"/></xsd:simpleType>

<xsd:simpleType name="myIntegerUnion"> <xsd:union> <xsd:simpleType> <xsd:restriction base="xsd:integer"/> </xsd:simpleType> <xsd:simpleType> <xsd:restriction base="xsd:string"> <xsd:enumeration value="N/A"/> </xsd:restriction> </xsd:simpleType> </xsd:union></xsd:simpleType>

3.2.3 XML Schema 中的派生复杂数据类型

下面的两种形式分别声明了一个无名的、以及一个命名的(名为 ComplexTypeName )复杂数据类型:

<xsd:complexType> ......</xsd:complexType >或者:<xsd:complexType name="ComplexTypeName

"> ......</xsd:complexType>

复杂数据类型的几种情况

1. 空元素(只包含属性、不包含 子元素和文本内容)

对于包含属性的空元素,定义过程非常简单,只需定义所需的属性及其数据类型即可。

<xsd:complexType name="ComplexType"><xsd:attribute name="Att1Name" type="someSimpleType1"/><xsd:attribute name="Att2Name" type="someSimpleType2"/>......

</xsd:complexType>

2. 只包含子元素,不包含 文本内容(可能包含 属性)

XML Schema 中提供了几种不同的容器(对应于不同的分组模式),以便表示其中子元素的出现顺序,它们分别是 xsd:sequence 、 xsd: choice 、 xsd:all 。

xsd:sequence

表示序列,即元素必须按照声明的顺序出现。 <xsd:complexType name="studentType">

<xsd:sequence><xsd:element name="firstname" type="xsd:string"/><xsd:element name="lastname" type="xsd:string"/>

</xsd:sequence></xsd:complexType><xsd:element name="student" type="studentType"/>

表示序列,即元素必须按照声明的顺序出现。 元素的声明必须放在某个容器中,而不能直接出现在 xsd:complexType 元素中,即使是只有一个子元素。

xsd: choice 表示从所包含的内容中选择其一。

<xsd:complexType name="PurchaseOrderType"> <xsd:sequence> <xsd:choice> <xsd:sequence> <xsd:element name="shipTo" type="USAddress"/> <xsd:element name="billTo" type="USAddress"/> </xsd:sequence> <xsd:element name="singleUSAddress" type="USAddress"/> </xsd:choice> <xsd:element name="items" type="Items"/> </xsd:sequence> <xsd:attribute name="orderDate" type="xsd:date"/></xsd:complexType><xsd:element name="PurchaseOrder" type="PurchaseOrderType"/>

xsd:all

表示其中所包含的内容不分先后顺序。 <xsd:complexType name="studentType">

<xsd:all><xsd:element name="firstname" type="xsd:string"/><xsd:element name="lastname" type="xsd:string"/>

</xsd: all></xsd:complexType><xsd:element name="student" type="studentType"/>

3. 只包含文本内容和属性,不包含 子元素

对于这种类型的元素,只包含简单内容(文本和属性),在进行声明时, XML Schema 中引入了一个新的元素,称为 simpleContent(用于表示“文本”、或者“文本+属性”)。

声明方法

方法 I 方法 II

<xsd:element name="ele_name"> <xsd:complexType> <xsd:simpleContent> <xsd:extension base="basetype"> ...... </xsd:extension> </xsd:simpleContent> </xsd:complexType></xsd:element>

<xsd:element name="ele_name"> <xsd:complexType> <xsd:simpleContent> <xsd:restriction base="basetype"> ...... </xsd: restriction> </xsd:simpleContent> </xsd:complexType></xsd:element>

示例 1

比如, shoesize 元素只包含属性 country 和文本内容(具体的 shoesize 大小,一个整数值): <shoesize country="france">35</shoesize>

<xsd:element name="shoesize"><xsd:complexType>

<xsd:simpleContent><xsd:extension base="xsd:integer">

<xsd:attribute name="country" type="xsd:string"/></xsd:extension>

</xsd:simpleContent></xsd:complexType>

</xsd:element>

xsd:extension 和 xsd:restriction 使用 xsd:extension 元素,可以对基础类型

进行扩展;但元素文本内容的类型实际上只能由 base 属性所指定的类型来决定,在 xsd:extension 元素中,只能定义与属性有关的内容( xsd:attribute 、 xsd:anyAttribute 、 xsd:attributeGroup )。

使用 xsd:restriction 元素,可以对基础类型进行限制;与 xsd:extension 一样,元素文本的类型是由 base 属性所指定的类型来决定,但是可以在 xsd:restriction 元素中使用各种限制方面 (Facet) 对其进行限制;

4. 同时包含子元素和文本(可能包含属性)

与 DTD 中一样,我们将这种类型的元素所包含的内容称为混合内容。

要定义这种复杂数据类型,需要使用 complexType 的 mixed 属性。

示例<letter letter_id="123"> Dear Mr.<name>John Smith</name>. Your order <orderid>1032</orderid> will be shipped on <shipdate>2007-07-13</shipdate>. </letter>

<xsd:element name="letter"> <xsd:complexType mixed="true"> <xsd:sequence> <xsd:element name="name" type="xsd:string"/> <xsd:element name="orderid" type="xsd:positiveInteger"/> <xsd:element name="shipdate" type="xsd:date"/> </xsd:sequence> <xsd:attribute name="letter_id" type="xsd:positiveInteger"/> </xsd:complexType></xsd:element>

3.2.4 有关类型声明的完整语法

前面介绍了如何声明简单数据类型和复杂数据类型,主要使用的是下面的简单的语法形式:

<xsd:simpleType name="simpleTypeName">......

</xsd: simpleType>以及:<xsd:complexType name="complexTypeName

">......

</xsd:complexType>

3.2.4.1 simpleType 元素的属性<simpleType final = (#all | List of (list | union | restriction)) id = ID name = NCName> Content: (annotation?, (restriction | list | union))</simpleType>

final 属性的值表示该数据类型不允许进行的操作的列表,比如本示例中,不允许使用列表对该类型进行派生。但是可以直接使用该类型。

#all 表示不能对该类型进行任何操作。

3.2.4.2complexType 元素的属性

abstract 属性表示该复杂类型是一个虚类型,只能用作其他类型的父类型。

<complexType abstract = boolean : false block = (#all | List of (extension | restriction)) final = (#all | List of (extension | restriction)) id = ID mixed = boolean : false name = NCName> Content: (annotation?, (simpleContent | complexContent | ((group | all | choice | sequence)?, ((attribute | attributeGroup)*, anyAttribute?))))</complexType>

XML Schema 中的面向对象特性( OO Features )——多态性

<xsd:complexType name="Class1" abstract="true"> <xsd:sequence> <xsd:element name="Class1_subelement" type="xsd:string"/> </xsd:sequence></xsd:complexType>

<xsd:complexType name="Class11"> <xsd:complexContent> <xsd:extension base="Class1"> <xsd:attribute name="Class11Attr" type="xsd:string"/> </xsd:extension> </xsd:complexContent></xsd:complexType>

<xsd:element name="obj" type="Class1"/>

<obj Class11Attr="att" xsi:type="Class11"><Class1_subelement>123</Class1_subelement>

</obj>

block 属性 如 果 不 希 望 使 用 多 态 性 , 可 以 使 用

complexType 的 block 属性(它的取值可能为 #all 、 extension 、 restriction )。

extension 和 restriction ,分别表示禁止使用任何通过扩展 /限制而派生的子类型的实例来代替声明为父类的元素。

block 和 final 属性是有区别的,因为即使 block=“#all” ,仍然可以派生新的子类型,而 final =“#all” 则表示禁止派生。对于 block 来说, #all 表示禁止使用任何子类型的实例来代替声明为父类的元素。

3.3 XML Schema 中元素和属性的声明 全局( Global )和局部( Local )的概念:

根元素 xsd:schema 的直接孩子称为全局的,如果是元素声明,则称之为全局元素;如果是类型声明,则称之为全局类型。

全局的对象只可能是元素声明或者是数据类型声明,而不可能是其他的内容。换句话说,其他内容不能够直接出现在 xsd:schema 根元素下,必须包含在元素声明和数据类型声明中。

3.3.1 元素的声明 先声明一个命名的类型 ele_type ,然后通过

名称进行引用

直接在元素的声明中包含一个无名的类型声明

<xsd:simpleType 或 xsd:complexType ...... name="ele_type">

......</xsd:simpleType 或 xsd:complexType><xsd:element name="ele_name" type="ele_type"/>

<xsd:element name="ele_name"> <xsd:simpleType 或 xsd:complexTyp

e>......

</xsd:simpleType 或 xsd:complexType>

</xsd:element>

3.3.1.1 XML Schema 中 element 元素的各种属性

<element abstract = boolean : false block = (#all | List of (extension | restriction | substitution)) default = string final = (#all | List of (extension | restriction)) fixed = string form = (qualified | unqualified) id = ID maxOccurs = (nonNegativeInteger | unbounded) : 1 minOccurs = nonNegativeInteger : 1 name = NCName nillable = boolean : false ref = QName substitutionGroup = QName type = QName> Content: (annotation?, ((simpleType | complexType)?, (unique | key | keyref)*))</element>

1. maxOccurs 和 minOccurs 属性 这两个属性用于限制元素的最大和最小出现次

数。 <?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 name="author" type="xsd:string" minOccurs="1" maxOccurs="3"/> <xsd:element name="price" type="xsd:decimal"/> </xsd:sequence> </xsd:complexType> </xsd:element></xsd:schema>

如果允许一 个元素出现无数 次,那么可以 让 maxOccurs="unbounded"

2. default 和 fixed 属性

default 和 fixed 属性用于指定元素缺省值和固定值 。

<xsd:element name="test" type="xsd:string" fixed="fixedstring"/>

3. ref 属性 ref 属性表示引用某个已经定义的全局元素。

<xsd:element name="person"> <xsd:complexType> <xsd:sequence> <xsd:element name="firstname" type="xsd:string"/> <xsd:element name="lastname" type="xsd:string"/> </xsd:sequence> </xsd:complexType></xsd:element>

<xsd:element name="employee"> <xsd:complexType> <xsd:sequence> <xsd:element name="ID" type="xsd:string"/> <xsd:element ref="person"/> </xsd:sequence> </xsd:complexType></xsd:element>

4. nillable 属性和 xsi:nil 属性

nillable=false 表示不允许某个元素的值为空,相当于关系数据库中的 NOT NULL ; nillable=true 表示允许某个元素的值为空。

<xsd:element name="studentid" type="xsd:integer" nillable="true"/>

必须使用 xsi 命名空间的另外一个属性 xsi:nil ,如果某个元素的 xsi:nil 属性值为 “ true” ,则表示该元素的文本内容为空。

<studentid xsi:nil="true"></studentid>

替换组( Substitution group ) 1 可能由许多国家的开发人员使用,从而希望 n

ame 元素对于不同的语言,使用不同的版本。比如,英语国家直接使用上面的 name 元素,而在中国则可以使用名为“姓名”的元素来代替“ name” 元素,以此类推。

<xsd:element name="name" type="xsd:string"/>

<xsd:element name=" 姓名 " substitutionGroup="name"/>

“替换组”的机制允许使用其他元素来替换原先定义的元素。替换组中包含一个头元素( Head Element )和进行替换的一组元素。

替换组( Substitution group ) 2 对于头元素和多个替换元素 :

替换元素的数据类型必须与头元素相同、或者是头元素数据类型的派生类型。

如果替换元素的数据类型与头元素相同,则无需单独说明;在本例中,没有指定“姓名”元素的类型,这表示该替换元素的类型与头元素 name 相同,都是 xsd:string。

在具体的 XML 文档中,如果使用一个替换元素替换了头元素,即使该替换元素的数据类型是头元素数据类型的派生类型,也不需要使用 xsi:type 来指定具体的类型。因为在替换之后,解析器可以通过替换元素的名称(不同于头元素的名称)来确定其具体类型。

在定义了替换组之后,仍然可以使用头元素(比如对于英语国家,仍然可以直接使用 name 元素),它只是提供了可替换的机制。

5. abstract 属性

abstract 属性的取值为 true 、 false ,缺省值为 false 。如果 abstract=true ,则表示该元素是一个纯虚的头元素。也就是说,在具体的 XML 文档中,它不能直接使用,必须用该替换组中的某个替换元素来替换它。

6. block 属性

block 属性的取值为集合 {extension, restriction, substitution} 的一个子集,用 #all 来表示这个集合的全集。

<xsd:complexType name="Class1" block="extension">

......</xsd:complexType><xsd:element name="obj" type="Class1"/> <xsd:complexType name="Class1" >

......</xsd:complexType><xsd:element name="obj" type="Class1" block="extension

"/><xsd:element name="anotherobj" type="Class1"/>

如果 block 属性的取值为 substitution ,则表示不允许对 该元素进行替换。

3.3.1.2 element 中的 unique 、 key 和 keyref

在定义元素的时候,可以在 xsd:element 元素中使用 unique 、 key 和 keyref 指定唯一值、键和键引用,它们分别类似于关系数据库中的 UNIQUE 约束、键约束和外键约束。

1. unique 约束

<unique id = ID name = NCName> Content: (annotation?, (selector, field+))</unique><selector id = ID xpath = a subset of XPath expression > Content: (annotation?)</selector><field id = ID xpath = a subset of XPath expression > Content: (annotation?)</field>

selector 元素包含 XML 路径语言 (XPath) 表达式,指定一个元素集,在其中由 field 元素指定的值必须唯一。必须有一个且只有一个 selector 元素。

每一个 field 元素均包含一个 XPath 表达式,指定对于由 selector 元素指定的元素集而言必须唯一的值(属性或元素值)。如果有多个 field 元素,则 field 元素的组合必须是唯一的。在此情况下,单个 field 元素的值对于选定元素不一定是唯一的,但所有字段的组合必须是唯一的。必须有一个或多个 field 元素。

Unique 约束的示例

unique.xsd orderByCustomer.xml

2. key 和 keyref 约束

key 元素的结构和 unique 大致相同,它要求所选内容在指定范围内必须是唯一的,并且通过 name 属性指定键的名称,以便由 keyref 进行引用。 keyref 元素中多了一个 refer 属性,该属性的值应该是一个 key 元素的名称,表示对该 key 元素的引用。 key 和 keyref 之间的关系就是关系数据库中主键和外键之间的关系。

<key id = ID name = NCName> Content: (annotation?, (selector, field+))</key><keyref id = ID name = NCName refer = QName> Content: (annotation?, (selector, field+))</keyref>

关系数据库中存在自参照关系的数据库表示例

cno cname cpno credit

1 数据库 5 3

2 数学 4

3 C 语言 3

4 操作系统 3 3

5 数据结构 3 3

Key.xsd

3.3.1.3 XML Schema 中的 元素组和 <any> 元素

在 XML 文档中,某些元素可能始终是成组出现的,那么可以将这些元素按照某种顺序,定义为元素组,以便在需要的时候进行引用。

<xsd:group name="persongroup"> <xsd:sequence> <xsd:element name="firstname" type="xsd:string"/> <xsd:element name="lastname" type="xsd:string"/> <xsd:element name="birthday" type="xsd:date"/> </xsd:sequence></xsd:group>

元素组的使用<xsd:element name="student" type="studentinfo"/><xsd:complexType name="studentinfo">

<xsd:sequence><xsd:group ref="persongroup"/><xsd:element name="stu_no" type="xsd:string"

/></xsd:sequence>

</xsd:complexType>以及:<xsd:element name="employee" type="employeeinfo"/><xsd:complexType name="employeeinfo">

<xsd:sequence><xsd:group ref="persongroup"/><xsd:element name="salary" type="xsd:integer

"/></xsd:sequence>

</xsd:complexType>

<any> 元素 在为 XML 文档编写 Schema 模式时,可能

模式中的有些部分无法确定、或者允许用户在某个位置添加任何所需的内容( Schema 文档中的任何全局元素),则可以使用 <any>元素。 <xsd:element name="person">

<xsd:complexType><xsd:sequence>

<xsd:element name="firstname" type="xsd:string"/><xsd:element name="lastname" type="xsd:string"/><xsd:any/>

</xsd:sequence></xsd:complexType>

</xsd:element>

3.3.2 属性、属性组和任意属性的声明 属性声明时各种属性的使用。 xsd:attribute 元素用于属性的定义,其中可以包含

name 、 default 、 fixed 、 ref 、 type 、 use 等属性,分别用于描述相应属性的特征。

default = string、 fixed = string 可以表示对应属性的缺省值和固定值。

ref = QName 可以表示引用某个外部的全局属性定义 。

use = (optional | prohibited | required) 可以表示所定义的属性是否必须出现、或者禁止出现。

属性组的声明和使用

<xsd:attributeGroup name="personattrgroup"><xsd:attribute name="firstname" type="xsd:string"/><xsd:attribute name="lastname" type="xsd:string"/><xsd:attribute name="birthday" type="xsd:date"/>

</xsd:attributeGroup>

<xsd:element name="employee"><xsd:complexType>

<xsd:attributeGroup ref="personattrgroup"/><xsd:attribute name="salary" type="xsd:integer"/>

</xsd:complexType></xsd:element>

anyAttribute 元素

使用 anyAttribute 元素,允许用户为指定的元素添加任何所需的属性 。

<xsd:element name="student"><xsd:complexType>

<xsd:attribute name="firstname" type="xsd:string"/><xsd:attribute name="lastname" type="xsd:string"/><xsd:attribute name="birthday" type="xsd:date"/><xsd:attribute name="stu_no" type="xsd:string"/><xsd:anyAttribute/>

</xsd:complexType></xsd:element>

3.4.1 XML Schema 的 PSVI 数据模型 XML Schema 所描述的数据模式不仅仅可用于对 XM

L 实例文档的数据进行有效性验证,而且在进行了验证之后,将在解析器中构成一颗新的 XML 文档树,其中每个节点将附加上 XML Schema 中所定义的具体类型,所得到的这种新的数据模型称为“经过 Schema 验证的信息集( Post Schema Validation Infoset , PSVI )”。

对于 XQuery、 XPath 等查询任务、以及其他处理 XML 数据的应用程序而言, PSVI 是非常重要的。

3.4.2 XML Schema 文档的目标命名空间和引用

<xsd:schema xmlns:xsd=“http://www.w3.org/2001/XMLSchema” targetNamespace="http://www.xml.com" xmlns="http://www.xml.com" elementFormDefault="qualified" attributeFormDefault="unqualified">...</xsd:schema>Schema 文档 somexsd.xsd

<root xmlns="http://www.xml.com" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.xml.com http://somesite/somexsd.xsd">......</root>XML 实例文档

elementFormDefault 属性

elementFormDefault 取值的含义

是否存在目标命名空间

elementFormDefault属性的取值 全局元素或类型 局部元素

不存在qualified 无命名空间 无命名空间

unqualified 无命名空间 无命名空间

存在qualified targetnamespace targetnamespace

unqualified targetnamespace 无命名空间

attributeFormDefault 属性

是否存在目标命名空间

attributeFormDefault属性的取值 属性

不存在qualified 无命名空间

unqualified 无命名空间

存在qualified targetnamespace

unqualified 无命名空间

attributeFormDefault 取值的含义

<?xml version="1.0" encoding="UTF-8"?><xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" elementFormDefault="unqualified" attributeFormDefault="qualified" targetNamespace="ts"> <xsd:element name="root"> <xsd:complexType> <xsd:sequence> <xsd:element name="element_a" type="xsd:string"/> <xsd:element name="element_b" type="xsd:integer"/> </xsd:sequence> <xsd:attribute name="att" type="xsd:string"/> </xsd:complexType> </xsd:element></xsd:schema>

<n1:root n1:att="String" xsi:schemaLocation="ts correct.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:n1="ts"> <element_a>String</element_a> <element_b>0</element_b></n1:root>

3.5 在 XMLSPY 中编辑和操作 XML Schema

1.创建和编辑 XML Schema 文档 2. 自动生成以及转换 XML Schema 文档

Recommended