XQuery3.0组合查询符合条件的内容.

来源:互联网 发布:乐视下载软件 编辑:程序博客网 时间:2024/06/06 19:58

近段时间在学习XQuery.学得越多感觉XQuery越实用,甚至于感觉用XML-XQuery的搭配比XML-XSLT的组合要发挥出更大的作用些.

特别在XQuery3.0/3.1推出了很多新的功能后.XQuery作为一种独立的语言确实要比XSLT强大得多.

今天偶然在XML论坛上见到多年前有人发布的一道题目:

<element name="abc" id="0001" project="xxx"> <att name="att1" type="string">san you</att> <att name="att2" type="string">big look</att> <att name="att3" type="string">san you</att> <att name="att4" type="number">234</att> <att name="att5" type="bool">false</att></element><element name="abcde" id="0002" project="xxx2"> <att name="att1" type="string">aaaa</att> <att name="att2" type="string">bbbb</att> <att name="att3" type="string">cccc</att> <att name="att4" type="number">1234</att> <att name="att5" type="bool">false</att></element>

对于上面的文档,使用xquery实现如下功能是否可行,如果能提供示例,不胜感激:

1 查询具name='att4',并且值等于234(以数值类型比较)的element元素
2 查询同时拥有条件为 name='att1' 值='aaaa'的<att/>元素 和 name='att2' 值=‘bbbb' 的<att/>元素的element,查询结果应为第二个element.


1.由于在强制类型转换如果不成功的话会产生错误.所以理论上来说用数值类型比较att的值是不现实的.

但是可以换一种方式来理解.比如预先判断att的值是否符合数字的匹配模式(正则),另外在XQuery3.0以后提出了try-catch的方式来处理错误.

所以题目1有存在两种方式来解决.代码如下:

declare function local:equal($att as xs:string,$value as xs:integer) as xs:boolean{if(matches(normalize-space($att),"\d+")) then (xs:integer($att) = $value) else (false())};declare function local:equals($att as xs:string,$value as xs:integer) as xs:boolean{try{   xs:integer($att) = $value}catch *{   false()}};for $element in doc("source.xml")/elements/elementfor $att in $element/attwhere $att/@name = "att4" and local:equals(string($att),234)return if(exists($att)) then($element) else()

通过在XQuery中自定义方法来解决.如果如果传入的参数符合数字的格式则按照数字格式来比较,否则直接返回false().并且在FLWOR中的where来调用函数.


2.题目2相对简单些.主要思想是通过定义两个变量来引用attr,然后分别判断这两个变量是否符合要求.代码如下:

for $element in doc("source.xml")/elements/elementlet $attrs as element(att)* := $element/attfor $attr1 in $attrsfor $attr2 in $attrswhere $attr1/@name="att1"       and xs:string($attr1) = "aaaa"       and $attr2/@name="att2"      and xs:string($attr2) = "bbbb"return $element

0 0
原创粉丝点击