XQuery查询语言及应用实例分析

来源:互联网 发布:js 控制div 上下居中 编辑:程序博客网 时间:2024/05/03 10:56
本文介绍了XQuery查询语言的主要特性,并通过实例讨论了XQuery语言在数据查询、转换等方面的应用。

引言

XML已经成为事实上的数据表示和数据交换的标准。开始,它的自描述和特定可扩展性等核心特性提供了不同应用程序之间消息传输所需的灵活性。特别是随着近年来Web Service的蓬勃发展,XML越来越多地活跃在数据交换和存储领域,用XML表示的半结构化数据越来越普遍,在B2B电子商务行业中尤其明显。面对XML数据量的指数级的增长,必然要求更有效的数据管理能力和更快、更精确的查询。因此,如何从XML数据源中准确有效地查询所需信息,也就变得越来越重要。





一、XQuery概述

XQuery工作组于1999年9月正式成立,其任务是创建一种灵活的查询语言以便从XML文档中抽取数据。目前W3C所公布的最新XQuery草案是2003年11月12日的版本,它还在不断的修订和完善之中[1]。作为一种新型的查询语言,XQuery汲取了其它多种查询语言的优点,适用于各种类型的XML数据源的查询,不仅查询功能强大,而且简洁灵活且易于实现。而且,XQuery还具有从多种数据库中检索信息的特点,它能对各种数据和文档进行查询。

XQuery构建在XPath规范之上,其核心是能够通过XPath表达式从文档选择特殊的节点序列。XQuery是一种将查询表示成表达式的功能语言。通过它所支持的多种表达式,它的查询可以有各种不同的形式。各种XQuery表达式可以完全嵌套,也支持子查询。目前,数据库业界的三大主流厂商Oracle、IBM、Microsoft都已经在各自的产品中提供了对XQuery规范的支持。






二、XQuery及其应用实例

1. 查询应用

XQuery具有强大的查询和检索功能,它通过各种由关键字、符号、操作数构成的表达式完成查询,其表达式的操作对象可以又是另一个表达式。作为一种函数语言,它还允许各种表达式进行相互嵌套。同时它也是一种对数据类型有要求严格的语言,表达式中的操作数,运算符和函数都必须是指定的类型[2]。

首先来看一个表述书籍信息的XML文档bib.xml的例子。

<bib><vendor id="id1_2">      <name>china-pub</name> <book>   <title>JAVA编程思想</title>   <publisher>机械工业出版社</publisher>  <year>2002</year> <author>    <firstname>Bruce</firstname>     <lastname>Eckel</lastname>   </author>  <price>99</price> </book><book>   <title>XML手册</title>   <publisher>电子工业出版社</publisher>    <year>2003</year> <author>     <firstname>Charles F.</firstname>      <lastname>Goldfarb</lastname>    </author>   <price>69</price>   </book></vendor>……</bib>

1. 1 XPath

XPath是一种能在XML文档中查找定位信息的语言,它能从XML文件中抽取单个项目或一组项目。 XPath类似于平时我们在计算机系统中使用的文件路径,就像我们熟知的C:/ WINNT 那样。通过XPath路径表达式,可以在XML文档中轻松地定位数据,确定节点。比如下面这个基本类型的XPath表达式(对应上面的XML文档):/bib/vendor/@id。这个表达式从文档根开始,选择所有 bib子元素,然后选择bib的所有vendor子元素,最后选择vendor子元素的所有id属性。当然,XPath表达式所提供的能力远远超过用这条简单语句所做的工作。

使用XPath可在XML层次结构中快速定位和提取信息,它的内建函数提供了全面的功能,可以方便的处理数值及文本数据。

下面列举一些典型的XPath路径表达式:(用“/”路径开始代表元素的绝对路径)

路径表达式 选择的XML文档部分 / 选择XML文档的根结点 /* 选择根结点的所有子节点,*匹配任意子节点 /bib 选择根结点的所有bib元素 //book 选择根结点的所有后代节点中的book元素 //@id 选择含有id属性的子节点 /bib/book[2] 选择bib的第2个子元素 //vendor[@id='id1_2']/book 选择符合“属性id=’id1_2’”的所有book元素 /bib/vendor/book[year>2002] 选择符合“元素year>’2002’”的所有book元素

当然,XPath还能实现很多其他的功能,具体请参看W3C的XPath规范[3]。

1. 2 FLWR表达式

XQuery 中最强大的特性是 FLWR 表达式(发音为 flower),它是一种典型的能够完成具有某种实际意义的查询的表达式。FLWR表达式包含模式匹配、过滤选择和结果构造这三种操作。FLWR 语句是 XQuery 所具有的最接近于 SQL 的语句。使用 FLWR 语句,可以用比 XPath 1.0 语句更自然的方法来创建特定的查询。[5]

FLWR表达式是由FOR—LET—WHERE—RETURN四个关键字定义的子句构成的,在最新的标准中则更新为FLWOR,O代表新加入的Order by子句。

FLWOR表达式分别代表FOR—LET—WHERE—ORDER BY— RETURN 的首字母缩略词。由此组成的FLWOR 表达式可以完成很多在 XSLT中难以完成的任务。它支持迭代并且可以把变量绑定到中间结果。对两个或多个文档进行连接和重构数据时这种表达式非常有用。每个 FLWOR 表达式都有一个或多个 for 子句、一个或多个 let 子句、一个可选的 where 子句、一个order by子句以及一个 return 子句。FOR 子句通过将节点绑定到变量,以便继续去循环遍历序列中的每一个节点;let 子句为一个变量赋一个值或一个序列;return 子句定义每个元组要返回的内容;对于where子句,如果其有效布尔值为真,那么该元组就被保留,并且它的变量绑定用在return子句中,如果其有效布尔值为假,那么该元组就被废弃。

下面是一个简单例子:

for $i in document("bib.xml")/bib/vendor/bookwhere $i/price>80return<HighPricedBook>{$i/title, $i/price}</HighPricedBook>   

此例没有用到let语句,它只是可选的。要注意的是,变量都是以符号$开头的,这些变量被绑定到不同的节点序列,然后通过语句进行传递。花括号{}代表输出信息,以及要进行求值的信息。可以看出,FLWOR表达式是一个有多种变化的表达式类型,它可以生成大量不同的查询实例。“return”关键字后面的操作项本身可以被另一个 FLWOR 表达式替代,可以不断将 FLWOR 表达式首尾相接,使XQuery具有非常丰富的表达能力。

其查询结果为:

<HighPricedBook>     <title>JAVA</title>     <price>99</price> </HighPricedBook>

1.3 其他功能

除路径表达式和FLWR表达式之外,XQuery还有5种基本的表达式模式:元素构造符、算子和函数表达式、条件表达式、限定表达式、列表构造符、数据类型表达式[4]。通过它们的多种组合,可以产生具有丰富而强大的查询检索功能的查询语句。

下面是一个使用了算术运算符‘+’的实例:

let $a:=document("bib.xml")/bib/vendor/book[1]/pricelet $b:=document("bib.xml")/bib/vendor/book[2]/pricereturn <total_price_of_books>{$a+$b}</total_price_of_books>

查询结果如下:

<total_price_of_books>168</total_price_of_books> 

在查询语句中,还可以使用if …then…else…这样的选择结构,比如下例:

for $i in document("bib.xml")/bib/vendor/bookreturnif ($i/price < 70)then <LowPricedBook>{$i/title, $i/price}</LowPricedBook>else <HighPricedBook>{$i/title, $i/price}</HighPricedBook>

查询结果如下:

<HighPricedBook>     <title>JAVA</title> <price>99</price> </HighPricedBook> <LowPricedBook>     <title>XML handbook</title><price>69</price> </LowPricedBook> 

2.转换应用

在进行应用集成时,某个领域的应用可以使用多种词汇表,如果这些应用之间要进行交互,包括数据的交换,那么针对不同词汇表对XML文档进行转换就很有必要了。这时XQuery就能很好的适应需求,因为它具有很多类似XSLT的从潜在的异构数据源中转换数据的功能。

下面我们来看一个利用XQuery实现文档转换的例子,它能将XML文档的属性转换为元素显示。这是一个作为输入的原XML文档,它描述了订单项目。

<Order id="1000001"><item id="111" qty="10"/><item id="123" qty="28"/><item id="135" qty="16"/></Order>

下面是实现转换功能所用到的Xquery语句。它只是简单的改变原文档的结构,加上了一些元素。

let $order:=document("Order.xml")/Orderreturn<PurchaseOrder><Order>{$order/@id}</Order><LineItems>{for $Item in $order/itemreturn<Item><Id>{string($Item/@id)}</Id><Qty>{string($Item/@qty)}</Qty></Item> }</LineItems></PurchaseOrder>

转换后的结果如下:

<PurchaseOrder><Order id="1000001"/><LineItems><Item><Id>111</Id><Qty>10</Qty></Item><Item><Id>123</Id><Qty>28</Qty></Item><Item><Id>135</Id><Qty>46</Qty></Item></LineItems></PurchaseOrder>

在本例中,当使用XML数据的多个应用采用了不同的词汇表,简化地考虑问题,当它们采用了不同的DTD(Schema)时,很可能出现这种情况,由于不同的应用基于不同的实际考虑,就会在用XML表述某些特征时将DTD(Schema)设计为自由选择使用元素或属性。这就涉及到了文档的转换。

当然,在实际需求中,词汇表之间的转换很可能比这个例子要复杂的多,但是从本例我们可以看出 XQuery的强大转换功能足以表述大部分这样的需求。因为XQuery有着非常灵活的构建结果树的机制,它在设计时已经考虑到了要利于结构转换,所以有些情况下用它做转换工作比用XSLT在实现语法上更简明。

3.更新应用

虽然现在最新的XQuery 1.0标准草案中还暂不支持更新操作,但这方面的研究进展很快,一些Native XML数据库产品如Tamino、Ipedo都已在各自的产品中提供了更新的功能。而且另一个组织XML:DB也提出了一种XUpdate语言草案。显然,与SQL/XML可以方便的进行更新操作相比,XQuery在这方面还不完善。这也正是目前XQuery与SQL/XML相比最明显的差距。XQuery中还没有定义用于更新XML文档中元素的语法。而SQL/XML的更新机制已经被定义了,也已被应用到Oracle和DB2中。





三、查询语言的比较

从前面的例子,特别是FLWR结构,我们可以看出,XQuery 具有类似于 SQL 的外观和能力,这是熟悉关系数据库的用户所欢迎的。那么数据库界的SQL标准对于XML的查询需求有什么新的支持呢。我们不妨来比较一下同为XML查询语言标准的SQL/XML和XQuery。作为2003年12月提出的最新的SQL:2003标准中的一部分,SQL/XML基于关系查询语言的扩展,特别增加了对XML的支持。

虽然SQL/XML和XQuery都是XML的查询标准,但它们基于完全不同的模型,SQL/XML更适合关系模型,它能提供在已有SQL环境上的完全访问, 包括XQuery1.0标准中不准备提供的特性,比如更新和全文本查询。另外,SQL/XML的优势还在于,数据库厂商在SQL的查询优化上已经积累了多年的经验。可以说,SQL/XML提供了能从关系数据中创建XML同时又能很好的支持已有的SQL环境中关系数据的功能。

对仅仅基于关系数据的查询,SQL/XML和Xquery能达到类似的效果。但是,它们对同一功能的实现机制可能是完全不同的,因为SQL/XML的操作介于SQL和XML之间,而XQuery则基于纯XML的范畴之上,它是从以XML为中心的角度上来考察问题的。

而XQuery最擅长处理“混合”文档,即同时包含叙述流和量化数据的文档。因此,对于跨越关系数据库和其它XML数据源的查询,XQuery就显示出了更重要的优势。

目前看来它们是互补的。SQL/XML和XQuery标准的制定者都希望在标准中加入对方的部分功能。但从长期看,开发人员可能希望在他们的所有数据源上保持XML抽象。在这种情况下,作为一种为处理复杂的数据而开发的丰富而全面的编程语言,XQuery可能将成为一种重要的标准。






四、总结

现在,XQuery标准还在不断发展和完善,总的来说,我们认为,XQuery对只需处理XML数据或者需要同时处理XML和关系数据的XML程序员来说是最好的选择,但它同样有不足,而且相对成熟的SQL来说,它的技术支持和经验都要少一些。我们能肯定,不管是SQL/XML还是XQuery都将会在XML查询中发挥重要的作用,而且,XQuery在通用的XML处理方面会成为重要的标准。

 本文转自: http://www.ibm.com/developerworks/cn/xml/x-xqueryl/index.html
原创粉丝点击