分享
 
 
 

关于如何更新XQuery的具体步骤介绍

王朝other·作者佚名  2008-05-19
窄屏简体版  字體: |||超大  

更新XQuery

XQuery有了一些新特性,内容包括从原子化到跟踪文件结构。

在"你所不了解的XQuery"(Oracle杂志,2003年5/6月刊)一文中,我介绍了XQuery,它是一项由万维网联盟(W3C)开发的技术,设计用来查询和操纵XML数据或任何能以XML形式出现的数据,如关系型数据库。那篇引文讨论了2002年11月发布的XQuery草案规范。2003年5月,W3C发布了新的XQuery草案规范,本文追踪报道了5月份发布的草案规范中最令人感兴趣的变化和新增加的特性,其中包括库模块、序(prolog)变量、外部函数以及用于调试、错误处理和格式化的新函数。

变化

5月草案增加了大量新特性,但是我首先讨论对现有特性所做的更改。有些更改是表面上的。 例如,document()输入函数(该函数使用给定的统一资源标识符[URI]返回一个文档)被改为一个新的更短的名字doc()。另外,曾经被写成{- comment -}的注释现在改用新的笑脸符号(: comment :)。是的,现在每个注释都成了一个笑话。

有些更改则是更根本的。也许最重大的改动就是distinct-values()函数不再返回节点(节点是XML结构,如元素、文档、注释以及文本节点),它只返回原子值(如整数或字符串)。尽管该函数仍然接受节点和原子值,但只返回原子值。任何进入该函数的节点都会被"原子化"并被当作原子值,然后以原子形式返回。

原子化的规则很复杂,这里给出一些基本的:由模式定义为布尔型的元素将被原子化为true/false布尔值。定义为整型的元素将被原子化为一个整数。没有被模式定义的元素将被原子化为节点的XPath字符串值(文本节点递归地连接在一起)。

为了说明:

distinct-values(<itemapple</item,

<itembanana</item, "grape")

返回值("apple","banana","grape"),假设在模式中没有声明 。在下面的例子中,如果我们假设 被模式定义为布尔型,那么下面的语句:

distinct-values(<status0</status,

<statusfalse</status)

返回false(),因为它是两个元素的原子值。记住false()是XQuery常量,表示"假"。

现在你也许会想,"当我想返回节点时,可以使用distinct-nodes()函数。" 是的,但该函数只能根据节点标识删除重复节点(那些完全相同的节点,类似于Java中引用的等效节点)。没有能删除等效节点的函数。这会使查询变得复杂,因为没有办法能轻松地删除等效节点。

回过头来看我以前的那篇文章"你所不了解的XQuery",你将发现有些示例会受到这一改动的影响。在那篇文章中,下面的查询返回了艺术家名字的惟一列表,其中每一个名字前后都带有 标记:

distinct-values(document("itunes.xml")

/itunes/Tracks/Track/Artist)

示例输出类似于:

<ArtistMarc Cohn</Artist

<ArtistPink Floyd</Artist

现在,执行同样的查询则返回原子值:

Marc Cohn

Pink Floyd

由于distinct-values()去掉了 标记(这是原子化过程的一部分),所以你必须在完成distinct-values()调用后添加标记,如下所示:

let $artists :=

distinct-values(doc("itunes.xml")

/itunes/Tracks/Track/Artist)

for $a in $artists

return <Artist{ $a }</Artist

不是每种情况都是这么轻松地得到处理。看一下W3C 使用案例文档中的示例1.1.9.4在2002年11月版与2003年5月版中是如何变化的。该示例返回每位作者的著作列表。它使用了distinct-values(),根据2002年11月的规范,它的代码如下:

<results

{

for $a in distinct-values(

document("http://www.bn.com/bib.xml")

//author)

return

<result

{ $a }

{

for $b in document(

"http://www.bn.com/bib.xml")

/bib/book

where some $ba in $b/author

satisfies deep-equal($ba,$a)

;

return $b/title

}

</result

}

</results

根据查询结果你不能直接分辨出姓和名,但每个 元素都由一个 和 名组成。distinct-values()调用返回具有惟一名字的 元素列表。对于2003年5月的规范,现在查询必须在姓和名上单独运行distinct-values(),而且在嵌套的FLWOR表达式中也没有将$a指定为惟一的作者:

<results

{

let $a :=

doc("http://www.bn.com/bib/bib.xml")

//author

for $last in distinct-values($a/last),

$first in distinct-values(

$a[last=$last]/first)

return

<result

{ $last, $first }

{

for $b in

doc("http://www.bn.com/bib.xml")

/bib/book

where some $ba in $b/author

satisfies ($ba/last = $last and

$ba/first=$first)

return $b/title

}

</result

}

</results

除了编写用户定义的distinct-deep-equal()外,没有更好的方法来完成这件事了,而该方法在纯XQuery中不能执行。(注:FLWOR(发音为"flower")表达式是XQuery的构建模块。这个名字来源于组成表达式的关键词For、Let、Where、Order by和Return}。

新函数

2003年5月的XQuery规范草案增加了三个新函数,它们肯定会非常有用。第一个是:

trace($value as item()*,

$label as xs:string) as item()*

trace()函数允许在查询的中间进行printf风格的调试。该函数有两个参数:要显示的值(可以是任意多个项的序列)以及要显示的这个值的字符串标签。为方便起见,函数返回$value传递的值。trace()输出的位置由你的引擎来决定。

该函数使你能够详细查看查询的内部过程。例如,下面的查询根据文档名返回在XQuery引擎中存储的所有文档的URI。通过增加一个trace()调用,我能够在排序前查看返回的每个URI:

define function uris() as xs:string* {

for $n in input()

return trace(

xs:string(document-uri($n)), "base:")

}

for $u in uris() order by $u return $u

输出结果可能如下:

2003-08-01 14:40:46 base: census.xml

2003-08-01 14:40:46 base: ipo.xml

当使用trace()和其他类似的函数时,记住在XQuery中每项内容都是一个表达式。没有语句!为了能够完成类似语句的操作,你可以采用在表达式之间加逗号的方法来创建一个序列。然后,单独计算每个表达式的值。在最终的结果序列中忽略所有返回空值的表达式。例如,下面是两个不影响结果的trace()调用:

trace((), "starting query"),

let $time := current-dateTime()

let $ignored := trace($time, "Got time")

return

<html

<head</head

<bodyCurrent time is { $time }</body

</html

请注意第一个trace()调用后面的逗号。它使查询返回一个具有两个项的序列,第一个trace()调用的结果为空,因而被忽略。一般人不了解这一情况,但高级查询实际上就是返回一个序列,因此在这种特殊情况下两端的括号不是必需的。查询"5, "是完全正确的。此外,在这个示例中你会看到,当编写一个FLWOR表达式时,你可以执行let子句右侧的任意代码,并且忽略该值。

5月份的草案还增加了error()函数:

error($srcval as item()?)

这个函数使用户能够报告一个错误,类似于抛出一个异常。$srcval被定义为item()?,意味着它可以是一个XML结构或原子,并且加上问号标记表示这是可选的。下面是一些示例应用:

error()

error("Missing source document")

error(<spanA <ibeautifully</i

formatted error</span)

error()调用就像发生异常时那样展开堆栈。遗憾的是,XQuery仍没有try/catch功能。因此,尽管你能抛出错误,但却不能从中恢复。

在5月份的草案中最后一个引人注目的新增函数有一个奇怪的名字:round-half-to-even()。它有两种形式:

round-half-to-even($srcval as numeric?)

as numeric?

round-half-to-even($srcval as numeric?,

$precision as xs:integer) as numeric?

在有一个参数的情况下,它的行为类似于round()函数,只是当一个数恰好落在其他两个数的中间时,它将参数取整为最接近的偶数值。数字理论家们会告诉你从统计学上讲这是一个更精确的取整算法。举例说明:

round-half-to-even(1.5) = 2.0

round-half-to-even(2.5) = 2.0

round-half-to-even(2.51) = 3.0

有第二个参数的情况使函数变得很有趣。第二个参数表示精确级,并允许将函数用于格式化小数值。例如:

round-half-to-even(3.567, 2) = 3.57

round-half-to-even(1113.567, -2) = 1100.0

round-half-to-even(1 div 9, 3) = 0.111

在声明中使用的数字数据类型是xs:decimal、xs:integer、xs:float、xs:double以及任何根据限制由它们导出的类型的一种简单表示。它用于XQuery规范中,但你不能在自己的查询中使用它。

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有