XQuery查询语言及应用实例分析
本文介绍了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文档l的例子。
<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子句。
xml技术的主要应用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("l")/bib/vendor/book where $i/price>80 return <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("l")/bib/vendor/book[1]/price let $b:=document("l")/bib/vendor/book[2]/price return <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("l")/bib/vendor/book return if ($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("l")/Order return <PurchaseOrder> <Order>{$order/@id}</Order> <LineItems>{ for $Item in $order/item return <Item> <Id>{string($Item/@id)}</Id> <Qty>{string($Item/@qty)}</Qty> </Item> } </LineItems> </PurchaseOrder> |
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论