XQuery 概述
DB2 9 提供了对 XQuery 的支持。XQuery 是一种专门为操作 XML 数据而设计的新的查询语言,它是 W3C 行业标准的一部分。XQuery 使用户能够在 XML 文档固有的层次结构中导航。因此,可以使用 XQuery 检索 XML 文档或文档片段。还可以编写包含基于 XML 的谓词的 XQuery,从而将不需要的数据从 DB2 将返回的结果中 “过滤出去”。XQuery 提供了许多其他功能,比如对 XML 输出进行转换以及将条件逻辑合并到查询中。
在学习如何使用 XQuery 之前,需要了解这种语言的一些基本概念。
XQuery 基础
XQuery 总是将 XQuery Data Model 的一个值转换为 XQuery Data Model 的另一个值。XQuery Data Model 中的一个值是由零个或更多条目组成的序列。条目可以是:
任何原子值
XML 节点(有时候称为 XML 文档片段),比如元素、属性或文本节点
完整的 XML 文档
XQuery 的输入常常是一个 XML 文档集合。
清单 1 显示一个 XML 文档,其中包含 8 个元素节点、1 个属性节点和 6 个文本节点。元素节点由元素标记表示。在这个文档中,Client、Address、street、city、state、zip 和两个 email 元素都是元素节点。如果仔细看看 Client 元素,就会发现它包含一个属性节点,客户的 id。文档的一些元素节点有相关联的文本节点。例如,city 元素的文本节点是 San Jose。
清单 1. 示例 XML 文档 |
图 1 显示这个示例文档中的节点。
图 1. 示例 XML 文档中的元素、属性和文本节点
XQuery 语言来源于 XPath(定义用户如何在 XML 文档中导航)和 XML Schema(让用户能够为文档指定有效的结构和数据类型)等其他 XML 标准。在本教程中,学习如何将 XPath 表达式结合到 XQuery 中。
XQuery 提供了几种不同的表达式,可以按照自己喜欢的任何方式组合使用它们。每个表达式都返回一系列值,这些值可以用作其他表达式的输入。最外层表达式的结果就是查询的结果。
本教程讨论两种重要的 XQuery 表达式:
路径表达式 允许用户在 XML 文档的层次结构中导航(或者说 “漫游”)并返回在路径末端找到的节点。 FLWOR 表达式 它很像 SQL 中的 SELECT-FROM-WHERE 表达式。它用来遍历一系列条目并可选地返回每个条目的某些计算结果。XQuery 与 SQL 的差异
许多 SQL 用户误认为 XQuery 与 SQL 非常相似。但是,XQuery 在许多方面与 SQL 差异很大,因为设计这种语言的目的是操纵具有不同性质的不同数据模型。XML 文档包含层次结构并有固有的次序。与之相反,关系 DBMS(或者更准确地说,基于 SQL 的 DBMS)支持的表是平面的和基于集合的,所以行是无序的。
数据模型中的这些差异使得用来支持它们的查询语言有很大差异。例如,XQuery 使程序员能够在 XML 的层次结构中导航。一般的 SQL(不带 XML 扩展)没有(也不需要)在表数据结构中 “导航” 的表达式。XQuery 支持有类型数据和无类型数据,而 SQL 数据总是要用特定的类型进行定义。
XQuery没有空值(null),因为 XML 文档忽略缺失的或未知的数据。SQL 使用空值表示缺失的或未知的数据。XQuery 返回 XML 数据的序列;SQL 返回各种 SQL 数据类型的结果集。最后,XQuery 只操作 XML 数据。SQL 操作按照传统 SQL 类型定义的列,SQL/XML(带 XML 扩展的 SQL)操作 XML 数据和传统类型的 SQL 数据。
XQuery 中的路径表达式
XQuery 支持 XPath 表达式,使用户能够在 XML 文档层次结构中导航,找到他们所需要的部分。详细讨论 XPath 超出了本教程的范围,但是我们在这里要看几个简单的示例。
XPath 表达式看起来非常像在操作传统计算机文件系统时使用的表达式。考虑一下在 Unix 或 Windows 目录中是如何导航的,就能够理解使用 XPath 在 XML 文档中进行导航的方式。
XQuery 中的路径表达式由一系列 “步” 组成,步之间由斜线字符分隔。在最简单的形式中,每一步在 XML 层次结构中下降一层,寻找前一步返回的元素的子元素。路径表达式中的每一步还可以包含一个谓词,它对这一步返回的元素进行过滤,只保留满足条件的元素。稍后将看到这样的一个示例。
一种常见的任务是从 XML 文档根(XML 层次结构的最顶层)开始导航,寻找感兴趣的某个节点。例如,要想获得清单 1 的文档中的 email 元素,可以编写下面的表达式:
清单 2. 导航到 email 元素 |
如果文档包含多个 email 元素,而您只想获得第一个,那么可以编写:
清单 3. 导航到第一个 email 元素 |
除了在路径表达式中指定元素节点之外,还可以使用 @ 符号指定属性节点,从而在元素中识别出属性。下面这个路径表达式导航到 id 属性等于 123 的 Client 元素中的第一个 email 元素:
清单 4. 指定属性节点和值 |
前面这个示例使用了一个基于属性值的过滤谓词。还可以根据其他节点值进行过滤。XPath 用户常常根据元素值进行过滤,比如下面的表达式返回住在加利福尼亚的客户的 zip 元素:
清单 5. 根据元素值进行过滤 |
可以使用通配符(“*”)匹配路径表达式中各个步上的任何节点。下面的示例获取在 Client 元素的任何直接子元素下找到的任何 city 元素。
清单 6. 使用通配符 |
对于我们的示例文档,这将返回值为 San Jose 的 city 元素。导航到这个 city 元素的更精确的方法是:
清单 7. 导航到 city 元素的更精确的方法 |
清单 8 给出几个其他类型的路径表达式示例。
清单 8. 更多路径表达式及其含义 |
注意,XPath 是大小写敏感的。在编写 XQuery 时记住一点很重要,因为这是 XQuery 与 SQL 不同的一个方面。例如,如果将路径表达式 “/client/address” 放进 XQuery,对于 清单 1 中的示例文档,不会返回任何结果。
XQuery 中的 FLWOR 表达式
人们常常提到 XQuery 中的 FLWOR 表达式。与 SQL 中的 SELECT-FROM-WHERE 块一样,XQuery FLWOR 表达式可以包含多个由关键字指示的子句。FLWOR 表达式的子句以下面的关键字开头:
for:遍历一个输入序列,依次将一个变量绑定到每个输入条目
let:声明一个变量并给它赋值,值可以是包含多个条目的列表
where:指定对查询结果进行过滤的标准
order by:指定结果的排序次序
return:定义返回的结果
我们来简要介绍一下每个关键字。我们将在一节中讨论 for 和 return,所以可以看到一个完整的示例。(如果没有 return 子句,表达式就不完整。)
for 和 return for 和 return 关键字用来遍历一系列值并为每个值返回某些结果。下面是一个非常简单的示例:for $i in (1, 2, 3) |
在 XQuery 中,变量名前面有一个美元符号(“$”)。所以,前面的示例将数字 1、2 和 3 绑定到变量 $i(每次绑定一个数字),并对于每次绑定返回 $i 的值。前面表达式的输出是 3 个值的序列:
1 |
看一个示例应该有助于澄清这一差异。请考虑下面这个使用 for 关键字的表达式,并注意返回的输出: