到现在为止,已经学习了大部分的内容,这里将开 始外围知识的学习。也就是说,将要开始学习SQL Server以外的知识。这里并不是说后面将要介绍的内容是RDBMS系统以外的内容,而是并不需要这些知识来构成SQL的功能。毕竟,SQL Server包含的内容太多,很难把所有的内容都压缩到一本书中进行介绍。
本章将从介绍这些额外内容的背景开始,接着将介 绍SQL Server支持XML的一些特性。这里的问题在于XML是完全独立的内容,它和到现在为止接触的关系系统有着很大的区别。为什么SQL Server要包含这么多的功能来支持它呢?简要的回答是,随着数据仓库的出现,对数据来说,XML可能最为重要。
XML的出现已经有好几年,但是由于争议比较大,它的实际应用没有达到应有的程度。大约从2000年开始,XML的应用范围越来越广,它将作为一种使实时数据更新服务(data feed)以及大小合理的数据文档可用的通用方式。XML提供了数据自描述的方法——也就是说,可以定义与XML文档一起的类型和确认信息,这样不论用户是谁(即使他们连如何连接SQL Server都不知道),他们都能够理解该数据的规则。
XML通常不是存储数据的好地方,但它确实是使得数据有用的一种引人注目的方式——同样地,使用XML的方法也在不断地发展。
综上所述,本章将学习以下的内容:
● XML的概念
● 其他与XML紧密相连的技术
提示:
前面提到过 XML通常并不是存储数据的好办法,但这也有例外情况。XML用作存储数据的一种方式是出于归档的目的。XML压缩的能力非常好,它使用一种非常开放的格 式,这样可以很好地理解这种格式。这里将用SQL Server 2005的备份功能作一下比较。十年以前,当您需要恢复一些旧的数据来回顾归档信息时,可能还没有安装SQL Server来处理这些旧的备份文件,但是很奇怪您可能会有解压缩(假设使用主流的压缩库如ZIP)以及阅读数据的工具。对于这些深入的归档来说,它们很 有用。
16.1 XML基础
有关XML的书籍已经很多(例如,Wrox出版社的Professional XML, 由Birbeck等人编写)。因为这本书的内容已经很完整,所以此处不会再添加有关XML本身的很多信息,而是假设您已经了解了XML的一些内容。但是, 我也知道即使XML近些年来成为了主流,还是有很多数据库人员认为XML“只是一项Web技术而已”,因此,他们没有花时间学过这方面的知识,而他们这样 的想法也是大错特错。
首先,XML是一项信息技术。它不是Web特有的技术。相反,由于以下的原因,可能会把XML误认为是Web特有的技术(通常是那些不理解XML的人们):
● XML是一种标记(mark up)语言,看上去和HTML很相似。
● XML通常很容易转换为HTML。同样地,它也成为了保存页面的信息部分、根据请求最终转换成HTML的流行方法——可以根据标准(例如哪种浏览器正在请求信息)发生单独的转换。
● Microsoft的Internet Explorer是第一个广泛使用的支持XML的产品。
● Internet经常是用作交换信息的方式,XML也很理想地适合这么做。
和HTML一样,XML是基于文本的标记语言。 它们的确继承于同一种语言,称为SGML。SGML存在的时间比Internet(至少是我们现在所认为的Internet)更为久远,并且用于印刷工业 或者用于政府相关的文档中。SGML中的“S”表示的意思并不简单——SGML很直观,但是并不清楚易学(我只能读懂所看过的35%的SGML文档。然 而,在阅读任何SGML时,我却肯定会感到不舒服)。而另一方面,XML更易于理解。
所以,您可能会问:“从哪里能得到XML标记的 列表呢?”这样的问题。答案是得不到这样的列表——至少和您想像中的答案不一样。XML只有很少的一些标记是它本身语言的一部分。而它能提供自定义的标记 以及使用由其他人(例如本章前面提及的产业集团)定义的标记的方法。XML在很大程度上和灵活性有关——它包含了通过使用XML模式文档或者以前的文档类 型定义(Document Type Definition)来为XML设定规则。
XML文档之所以成为XML是因为它有很少的规 则。这里的关系在于它必须是所谓的良好格式。后面将简要介绍良好格式的概念。仅仅因为XML文档满足良好格式的标准不能说明它有效。有效的XML文档不仅 是良好格式的,而且不能违反XML模式或文档引用的DTD加在其上的任何限制。本章后面将简单地介绍DTD和XML模式的内容。
也可以对XML进行转换。这里的意思是指可以很 容易地把XML转换成完全不同的XML表示或者甚至是非XML的格式。最为常见的应用是把XML转换成为HTML供Web使用。这种转换需要将HTML和 XML进行比较并对照。简单地说,XML和信息有关,而HTML和表示有关。
XML中存储的信息通过使用元素 (element)和属性(attribute)来表示。元素通常通过使用开始和结束标记(会有例外情况,后面将会介绍)来创建,并且用一个区分大小写的 名称来标识(不允许有空格)。属性是进一步描述元素的项,并且嵌入到元素的开始标记内。属性值必须在匹配的单引号或双引号内。
16.1.1 XML文档的各个组成部分
这里已经介绍了一些名称,它们是有意义的,但在开始深入介绍之前,我们先停下来学习一些术语,当谈及XML文档的时候将用到这些术语。
这里真正要做的是提供可能会碰到的XML文档中所有重要部分的列表,如图16-1所示。其中许多文档部分是可选的,而另一些则不是。在某些情况下,其中的一项必须以另一项为前提。在其他的情况下,文档的一些部分和其他部分相对独立。

图 16-1
这里采用的是层次结构的方法(某些内容内部的内容将列在其所属内容之后),这样做很有意义,因为在给定的XML文档中将会顺序地碰到它们。
1. 文档(Document)
文档包含从第一个字符到最后一个字符的所有内容。当引用一个XML文档时,引用的既是结构,又是该特定XML文档中的内容。
2. 声明(Declaration)
从技术上说,声明是可选的,但是从实际应用来说,通常要包含它。如果它存在,那么它必须在文档中最先出现。在声明之前不能出现其他内容,甚至是空白处(空格、回车、制表符)。
声明通过问号(表示这个标记是预处理指令)以及xml名称的特殊标记创建:
<?xml version="1.0"?>
声明有一个必需的属性(该属性进一步描述元素)——版本号(version)。在前面的示例中,已经声明了这是XML文档,并且它遵循XML规范的1.0标准。
声明可以有额外的属性——这个属性称为 encoding,它描述了这个XML文档使用的字符集的特性。XML可以处理一些不同的字符集,最重要的是UTF-16和UTF-8。UTF-16本质 上是Unicode规范,它是16位的编码规范,适用于当今世界大多数使用的字符。默认的编码方法是UTF-8,它与以前的ASCII规范兼容。完整的声 明如下:
<?xml version='1.0' encoding='UTF-8'?>
提示:
规范严格禁止使用以字母xml开始的元素—— 保留它们以供将来语言的扩充。
3. 元素(Element)
元素用作保存描述信息——它可以是任何内容。元素会为描述信息定义一个清楚的开始和结束点。通常,元素存在于一个配对的开始和结束的标记中。然而,开始标记可以自结束——基本上可以定义成为空元素。
XML元素的结构和HTML标记的结构很相似。开始标记以左尖括号(<)开始,包含名称以及可能的属性,最后以右尖括号(>)结束:
<ATagForANormalElement >
这个规则的一个例外是该元素可以自结束,这种情况是在结束标记的右尖括号之前有一个“/”:
<AselfClosingElement/>
结束标记和开始标记很相似(区分大小写),但要在需要结束的元素名称前以一个斜线(/)开始:
<ATagForANormalElement > <== Opening Tag
Some data or whatever can go in here.
We're still going strong with our data.
</ATagForANormalElement > <== Closing Tag
元素也可以包含属性(稍后将介绍)作为元素的开始标记(但不是结束标记)的一部分。最后,元素可以包含其他的元素,但是在结束外层元素之前必须先结束内层的元素:
<OuterElement>
<InnerElement>
</InnerElement>
</OuterElement>
当要介绍良好格式的概念时,将回来介绍这些元素。
4. 节点
当您指定组成XML文档的层次结构时,它以熟悉的树结构模型结束,在任何层次结构关系中会碰到该模型,如图16-2所示,树中的每个交集点称为节点。

图 16-2
XML文档的内容可以通过基于节点层次以及特定节点的属性值和元素值导航。
“根”节点
可能XML文档中最容易混淆的地方在于所谓的 “根节点”。每一个XML文档都必须有一个(不多不少)根节点。根节点是包含文档中其他元素(如果有其他元素)的节点。可以把根节点想像成把其下面的所有 节点结合在一起并且在任何特定XML文档的作用域内为它们提供结构的统一节点。那么,会发生混淆的地方在何处呢?混淆的情况通常会分为两种:人们不知道需 要有一个根节点(现在您知道了),以及他们不能理解根节点命名的方式(稍后将会介绍)。
因为通常的说法是“必须有一个根节点”,所以人 们通常把它理解为必须有一个节点称为root。的确,您可能会偶尔发现XML文档确实有一个根节点命名为Root(或root或ROOT)。但是现实的情 况是,根节点和其他任何元素一样,都遵循相同的命名模式,除了一点例外——名称在文档中必须唯一。也就是说,整个文档中,其他的元素不可以和根节点有相同 的名称。
注意:
根节点的存在是XML文档和XML片段的一个重要区别。通常,当从SQL Server中提取某些内容时,只能提取整个文档中的XML的一小部分,此处称之为XML片段。因为XML片段并不是整个文档,所以并不期望这些片段有根节点。
5. 属性(Attribute)
属性存在于元素的上下文中。对它们的实现是描述元素的更进一步的方式,属性放置在元素的开始标记的边界范围内:
<SomeElement MyFirstAttribute="Hi There" MySecondAttribute="25">
Optionally, some other XML
</SomeElement>
无论属性值是何种信息的数据类型,必须用单引号或双引号包含属性值。
提示:
默认情况下,XML文档没有数据类型的概念。本章的后面将介绍描述单文档应用程序规则的方法。到那时,可以看到保证数据类型的一些方法——为其设置规则,而XML自己不会这么做。
6. 没有缺点——良好格式
定义XML如何组织的规则——也就是说,可以使用何种元素、定义元素的方法、元素所拥有的部分——这些都是关于XML文档是否是良好格式的规则。
事实上,所有基于SGML的语言都有良好格式的概念。甚至是HTML也有一些良好格式的概念——这在很大程度上是因为HTML更为宽容,并且浏览器能够忽略许多错误。
如果熟悉HTML语法,那么您已经了解了一些基于标记语言的晦涩内容。XML有着更为严格的一些规则。简要的解释如下:
● 每一个XML文档必须有唯一的“根”节点。
● 每一个标记都必须有匹配的(区分大小写)结束标记,除非开始标记自结束。
● 标记不能跨越其他标记。
● 除非是XML分析器识别的字符,否则不能使用限制的字符。如果需要表示任何特殊的字符,那么需要使用转义序列(它会转换所请求的字符)。
下面是一个良好格式的文档的示例:
<?xml version="1.0" encoding="UTF-8"?>
<ThisCouldBeCalledAnything>
<AnElement>
<AnotherElement AnAttribute="Some Value">
<AselfClosingElement AnAttributeThatNeedsASpecialCharacter="
Fred"s
Flicks"/>
</AnotherElement>
</AnElement>
</ThisCouldBeCalledAnything>
提示:
这里的声明不需要一个结束标记。这是因为声明是预处理指令,而不是元素。从本质上讲,它告诉XML分析器在其开始真正处理XML业务之前需要知道的内容。
这是关于XML文档是良好格式的一个非常简短的示例,但是它很好地概括了本书中介绍的XML有限范围内的基础内容。
提示:
理解这些概念对于理解下一章的内容(至少是理解)很重要。下面介绍的示例会加强您的理解,但是如果看过XML示例还是觉得混淆,那么可以再学习一下上面的示例或者参考Professional XML或其他XML的书籍。在学习本章最后的样式和模式问题之前,必须理解这些问题。
7. XML示例
如果有什么主题贯穿于本书,那么就是本书会用示例来解释内容。前面提到过,本书不是关于XML的书籍,所以这里不准备先介绍示例,而是先来看一下谈论的话题。
在本章剩下来的部分以及下一章中,您将发现如果 您有一些XML编辑工具,那么一切将会变得简单很多。因为XML是基于文本的,所以可以在记事本中简单地打开并编辑XML文档——问题在于不能获得任何错 误的检测。那么如何知道该文档是良好格式的呢?如果文档只有几行,可以大致地看一下,但如果是完整的文档或是XSL文档,那么检测会变得困难。
提示:
作为边注,可以在Microsoft的Internet Explorer中打开文档来执行一个快速的检测,检测XML是否是良好格式。如果文档不是良好格式,那么它会报告错误。
作为示例,将介绍Northwind中数据的XML表示。在本例中,将看到一些订单的信息。下面将首先介绍一些内容,然后在此基础上深入介绍。
首先,对于任何XML文档来说都需要一个根节点。可以对根节点进行任意的命名,只要该名称在文档中唯一。一种常见的解决方法是命名该根节点为root。另外一个常见的方法是把它命名成为该特殊XML文档所表示的内容。
这里开始介绍一个简单的示例,它只使用根节点:
<root>
</root>
我们如此迅速地就创建了第一个良好格式的XML文档。注意它没有包含前面介绍的<?xml>标记。这里可以把它加进去,但它只是一个可选项。与该标记相关的唯一的限制是,它必须在最前面。为了最佳实践和清楚明了,这里增加了这个选项:
<?xml version="1.0" encoding="UTF-8"?>
<root>
</root>
事实上,根据XML的规则,任何以<?xml>开始的标记都是保留的标记——也就是说,不能命名该标记,因为当发布xml的新版本时,它们是保留给W3C现在和将来的使用。
这里已经有了第一个良好格式的XML文档。遗憾的是,该文档太简单——它不能说明任何内容。对于本例来说,想要描述订单的信息,所以需要向其中加入一些描述订单的信息。这里以Order标记作为开始:
<?xml version="1.0" encoding="UTF-8"?>
<root>
<Order/>
</root>
这看上去没什么变化,不是吗?现在知道,该XML文档中已经有了一个订单,但是还没有关于它的任何信息。这里通过添加一些属性来扩展它:
<?xml version="1.0" encoding="UTF-8"?>
<root>
<Order CustomerID="ALFKI" OrderID="10643" OrderDate=
"1997-08-25T00:00:00" />
</root>
这里并没有用到什么高深的知识,可以理解订单的基本内容:
● 客户的ID号是ALFKI
● 订单ID号是10643
● 订单日期是1997年8月25日
基本上,它和SQL Server中Northwind数据库的Orders表中的一行记录等价。如果客户有多个订单,则会有如下所示的记录:
<?xml version="1.0" encoding="UTF-8"?>
<root>
<Order CustomerID="ALFKI" OrderID="10643" OrderDate=
"1997-08-25T00:00:00" />
<Order CustomerID="ALFKI" OrderID="10692" OrderDate=
"1997-10-03T00:00:00" />
<Order CustomerID="ALFKI" OrderID="10702" OrderDate=
"1997-10-13T00:00:00" />
<Order CustomerID="ALFKI" OrderID="10835" OrderDate=
"1998-01-15T00:00:00" />
</root>
虽然这是一个合法的而且良好格式的XML文档, 但是它并不能真正地表示期望的数据的层次结构。在本例中,想要有一定区别地创建该XML,并且表示如下概念:客户通常在该层次结构链中的更高层(它们是订 单的父节点)。可以通过修改表示客户的方法来表示这种层次结构。这里使客户成为一个元素,而不是一个属性——它将包含自己的属性——而在客户元素的内部包 含这个特定的客户订单:
<?xml version="1.0" encoding="UTF-8"?>
<root>
<Customer CustomerID="ALFKI" CompanyName="Alfreds Futterkiste">
<Order OrderID="10643" OrderDate="1997-08-25T00:00:00" />
<Order OrderID="10692" OrderDate="1997-10-03T00:00:00" />
<Order OrderID="10702" OrderDate="1997-10-13T00:00:00" />
<Order OrderID="10835" OrderDate="1998-01-15T00:00:00" />
</Customer>
</root>
如果有多位客户,那么也不会有问题——这里只要再添加另一个客户节点即可:
<?xml version="1.0" encoding="UTF-8"?>
<root>
<Customer CustomerID="ALFKI" CompanyName="Alfreds Futterkiste">
<Order OrderID="10643" OrderDate="1997-08-25T00:00:00" />
<Order OrderID="10692" OrderDate="1997-10-03T00:00:00" />
<Order OrderID="10702" OrderDate="1997-10-13T00:00:00" />
<Order OrderID="10835" OrderDate="1998-01-15T00:00:00" />
</Customer>
<Customer CustomerID="ANTON" CompanyName="Antonio Moreno Taquería">
<Order OrderID="10365" OrderDate="1996-11-27T00:00:00" />
<Order OrderID="10507" OrderDate="1997-04-15T00:00:00" />
<Order OrderID="10535" OrderDate="1997-05-13T00:00:00" />
<Order OrderID="10573" OrderDate="1997-06-19T00:00:00" />
</Customer>
</root>
的确,这可以进入到无限的层次中(当然也服从于分析器可以处理)。例如,可以在订单中添加一个层次放置订单中的单个行式项。
8. 确定元素与属性
这里首先要理解,没有什么确定的而且快速的规则可以决定是元素还是属性。属性描述了元素的特性。子元素——或者元素的子节点有着同样的效果。那么,如何决定具体的属性呢?为什么属性是必需的?和现实中的大多数事情一样,这是平衡行为的内容。
属性在其值是一对一关系以及它是元素的继承部分时很有意义。例如,在Northwind中,每一个客户ID只有一个公司名称——这对于属性来说是理想的情况。当把关系数据转换为XML的时候,表中的列会成为元素的一个属性,该元素直接和表中的行相关。
元素在元素自身和描述该元素的内容之间有一对多 关系时更有意义。在本章前面的示例中,对每一个客户会有多个订单。从技术上说,可以使每一个订单成为客户元素的属性,但是需要一次又一次地重复许多的客户 信息。同样地,如果Northwind数据库允许客户有别名(多个名称)的概念,那么可以在客户下面有“名称”元素,它的属性用来描述单个名称的实例。
提示:
不管如何选择,您需要坚持本书中多次强调的规则——前后一致。当在某处把给定的某个性质定义为属性时,在其他地方需要使它保持为属性,除非它的性质和在新位置中使用的性质有所不同。再提醒一次:前后一致。
16.1.2 命名空间
虽然有创建自己的标签、从其他来源混合和匹配数 据以及自己定义处理的自由,但是总会碰到在何处使用何种名称的冲突。例如,对于为库构建的应用程序来说,和另一个用来描述字体的(可能用它来描述字符集和 一系列字形之间的关联)应用程序相比,名为letter(对于某些人来说,信件(letter)是一个人写给另一个人的文档)的元素可能会有完全不同的结 构、规则以及含义。
为了进一步说明该示例,XML的性质是,世界上 的行业组织都在逐渐地统一描述该行业不同信息的命名规则和结构的约定。库组织可能已经统一了元素的格式来描述书籍、戏剧、电影、信件、短文等。同时,操作 系统和/或图形产业界已经统一了元素的格式来描述图片、字体以及文档布局。
现在,想像一下不幸的开发者被要求编写一个应用 程序,该应用程序提供库的内容。很明显,库内容经常会使用像字体这样的内容——所以,在XML中引用称为letter的内容时,是引用和字体有关的内容还 是一封某人写给另一个人的信件呢(假设是Thomas Jefferson写给George Washington的)?这里产生了冲突,需要方法解决这个问题。
这就是命名空间的价值所在。命名空间描述了元素 和属性的域以及它们的结构。会把库中支持信件(letter)的结构描述成库的命名空间。同样的,图形产业可能会有它们自己的命名空间,该命名空间可以描 述与该产业相关的字体(letter)。有关命名空间的信息存储在一个参考文档中,可以使用统一资源标识符(Uniform Resource Identifier,URI)找到它们,URI是个特殊的名称,它和URL很相似,最终会解析为参考文档。
当要建立XML文档来同时引用库以及图形结构 时,只要简单地引用这些产业各自的命名空间。另外,将限定元素和属性,它们的性质是由命名空间描述。通过使用命名空间来限定名称,可以确保如果文档有结构 不同、但名称相同的元素,那么可以引用文档的部分内容,这样可以确保并没有引用错误类型或属性。
为了引用整个文档的命名空间,只要简单地添加引 用,把它作为根节点的一个特殊的属性(称为xmlns)。这里要提供本地名称(如何引用命名空间)以及最终解析为参考文档的URI。如果想在分配命名空间 的节点的作用域范围内应用该特殊的命名空间,那么也可以在文档中为其他节点添加命名空间的引用(再次使用xmlns)。
下面是一个XML文档的示例(从技术上说,这就是所谓的模式),下一章将会用到它。请注意一下其中和命名空间相关的内容:
文档引用了3个命名空间——XDR(碰巧这是个XDR文档)、Microsoft数据类型的命名空间(它会建立一个关于不同数据类型的数量以及性质的列表)以及为了使用SQL Server XML集成而使用的特殊SQL Server命名空间。
一些属性(包括根节点的属性)由命名空间的信息加以限定(例如,参考sql:relation属性)。
<?xml version="1.0" encoding="UTF-8"?>
<Schema xmlns="urn:schemas-microsoft-com:xml-data"
xmlns:dt="urn:schemas-microsoft-com:datatypes"
xmlns:sql="urn:schemas-microsoft-com:xml-sql"
sql:xsl='../Customers.xsl'>
<ElementType name="Root" content="empty" />
<ElementType name="Customers" sql:relation="Customers">
<AttributeType name="CustomerID"/>
<AttributeType name="CompanyName"/>
<AttributeType name="Address"/>
<AttributeType name="City"/>
<AttributeType name="Region"/>
<AttributeType name="PostalCode"/>
<attribute type="CustomerID" sql:field="CustomerID"/>
<attribute type="CompanyName" sql:field="CompanyName"/>
<attribute type="Address" sql:field="Address"/>
<attribute type="City" sql:field="City"/>
<attribute type="Region" sql:field="Region"/>
<attribute type="PostalCode" sql:field="PostalCode"/>
</ElementType>
</Schema>
sql数据类型引用了一些特殊的属性。此处不需要担心Microsoft的数据类型命名空间是否也有字段或关系数据类型,因为完全限定了属性的名称。即使数据类型的命名空间没有称为字段的属性,XML分析器仍然会根据sql命名空间的规则来对它进行处理。
16.1.3 元素的内容
另一个关于XML和元素的值得一提的概念(与现在的内容很接近)是元素的内容。
元素可以在超过属性层以及嵌套元素的范围之外包含数据。虽然嵌套的元素是元素内容的一种形式(一个元素包含另一个元素),但是XML也允许在元素中包含行文本的信息。例如,可能会有如下所示的XML文档:
<?xml version="1.0" encoding="UTF-8"?>
<root>
<Customer CustomerID="ALFKI" CompanyName="Alfreds Futterkiste">
<Note Date="1997-08-25T00:00:00">
The customer called in today and placed another order. Says they really like our
work and would like it if we would consider establishing a location closer to their
base of operations.
</Note>
<Note Date="1997-08-26T00:00:00">
Followed up with the customer on new location. Customer agrees to guarantee us
$5,000 per month in business to help support a new office.
</Note>
</Customer>
</root>
Note元素的内容,就像“The customer called...”,既不是元素也不是属性,但是它们是有效的XML数据。
注意这些数据在XML中,但是SQL Server不会根据这种格式输出数据。RDBMS系统的行/列方法更适合于元素和属性。为了能输出上面的注释数据,需要把数据转换成为新的格式。本章的最后将介绍转换。
16.1.4 有效的与良好格式的——模式和DTD
如果XML文档是良好格式的,并不能说明它是有效的XML。这里想要告诉您,除非XML能通过一些规范文档的形式进行验证,这个XML才被认为是有效的。如今,只有两种官方类型的规范文档——文档类型定义(Document Type Definition,DTD)和XML模式。
这两种文档的基本前提相同。虽然XML希望能够定义大多数XML文档的基本结构,但是DTD和XML模式所探求定义的规则只是针对一类XML文档。这两种方法实现起来略有不同,它们都有各自的优点:
● DTD:经证明它很不错。SGML(XML是SGML的应用程序,可以认为SGML是XML的超集,但是很难学会它)利用了DTD,它的优点是人们都能接受它。现在有很多DTD可供使用。
它的缺点在于这个DTD在以前的语句中有效。这里不是说以前的内容未必好,但是在这种情况下,DTD确实不能跟上文档技术发展的脚步。DTD不能真正地允许类似限定数据类型这样的操作。
● XML模式:XML模式有着强类型的明显优势。它们的好处在于可以有效地建立自己的复杂数据类型——这种类型是由一个或多个其他数据类型(包括其他复杂的 数据类型)组成的,或者需要特殊的模式匹配(例如,社会保障号码只是一个数字,但是它有特殊的格式,可以通过XML模式对它进行强制的格式化)。XML模 式还有一个优点,它本身就是XML文档。这意味着编写XML文档的很多技术都适用于编写XML模式(虽然要学的内容还很多),而这些模式本身也是自描述的 ——使用另一个模式来对它进行验证。