XPath(转)[4]

[入库:2005年8月19日] [更新:2007年3月24日]

本文简介:选择自 miki52777 的 blog

</everyone>

上面的表达式将会返回一个正确的xml文档。请注意在这个例子中的标签 <everyone> 和 <who> ,是原样返回的。同时需要注意的是为了使return语句正常执行,必须包含一个单一的实体。
<everyone> 
   <who> <name> hari </name> </who> 
   <who> <name> john </name> </who> 
   ...
   <who> <name> leu </name> </who>
</everyone>

请注意上面的查询返回的是<name>元素。如果我们想仅仅显示名字的值而不显示出任何的标签该如何做呢? 我们需要使用text()函数。在上面的查询中,将"//name" 改为"//name/text()" ,将"$e"改为"$e/text()"。下面的查询就使用了这种方法。
for $e in document ("emp.xml")//name 
return $e/text() 
这个查询返回了一系列没有标签的名字。这说明xquery查询是可以根据用户或者应用程序所预期的情况定制的。xquery是从一种叫做quilt的语言中发展起来。 
hari
john 
...
leu 
这里有另外一个例子。  

for $d in distinct(document("emp.xml")//dname) 
let $e := document("emp.xml")//entry[dname = $d] 
return 
   concat($d/text(), " department has ", numformat("##", count($e)), 
" employee(s).") 

将会输出下面的结果: credit department has 1 employee(s).
toys department has 2 employee(s).
shoes department has 1 employee(s).
audit department has 1 employee(s).

条件表达式(conditional expression)
在前面的例子中我们已经初步接触了一些if then else语句的用法,下面我们来具体看看他们的语法格式:
if <条件表达式> then <表达式一> else <表达式二>
在条件表达中,条件表达式应当赋值为布尔值,或者是一个能被转换为布尔值的类型。如果值是为真,整个条件表达的结果的值和表达式一的值一样。否则和表达式二一致。下面提供给读者一个简单的例子:

<report> 
for $e in document("emp.xml")//entry 
return 
   <entry> 
      $e/name, 
      <proposedsal> if ($e/salary .>=. 60000) then 100000 else 200000</proposedsal> 
   </entry> 
</report>

元素构造器(element constructor)
在写查询语句的时候,你可能需要创建新的元素作为输出的一部分。元素构造器便提供这样的功能。一个简单的元素构造的例子如下:
<newelement>xquery language</newelement>
新元素的内容可以是指定的,也可以是计算产生的。
函数调用(function call)
这里函数的概念和其他程序设计语言中的函数概念是完全相同的。我们来看一个例子:
下面的函数返回xml文档的最大深度。
随后是一个计算partslist.xml 文档深度的调用。

define function depth(element $e) returns xs:integer
{
   {-- an empty element has depth 1 --}
   {-- otherwise, add 1 to max depth of children --}
   if (empty($e/*)) then 1
   else max(for $c in $e/* return depth($c)) + 1
}

depth(document("partlist.xml"))

高级话题与应用
求和 
在xquery当中,求和通过let和sum可以很简便的完成,在sql中,要使用"group by"与"having"语句。但是在sql当中,"group by"和"having" 只能和一个from语句对应,而在xquery当中可以使用多个let语句。下面的例子是按照部门返回工资总额。 

<deptpayrolls> 
for $d in distinct(document("emp.xml")//dname) 
let $s := document("emp.xml")//entry[dname = $d]/salary 
return 
   <deptpayroll> 
      $d, 
      <sumsal> sum($s) </sumsal> 
   </deptpayroll> 
</deptpayrolls> 

如果想得到大于等于70000的工资,我们应当做下面的查询。
<specialdepartments> 
for $d in distinct(document("emp.xml")//dname) 
where every $s in document("emp.xml")//entry[dname = $d] 
      satisfies ($s/salary >= 70000)
return 
   <deptavg> 
      $d, 
      <avgsal> avg(document("emp.xml")//entry[dname = $d]/salary) </avgsal> 
   </deptavg> 
</specialdepartments> 

值得注意的最重要一点是。在kweelt当中我们使用".>=." 而不是使用 ">="e uses ".>=."。最大的障碍是kweelt不支持数词。因此 "every x satisfies c(x)" 在kweelt不起作用。
设想一个等价表达式"not(some x satisfies not(c(x))" 尽管这样还是含有数词,但是它提供给我们一种间接的方式:首先我们在$s中收集满足not(c(x))的元素x,在where从句中使用"not exists ($s)" 来过滤掉已经通过for语句但是不符合这个要求的部分。剩余的部分就是所需的,并且将在return语句执行后被释放出来。因此我们得出了下面的查询。 

<specialdepartments> 
for $d in distinct(document("emp.xml")//dname) 

本文关键:XPath(转)
  相关方案
Google
 

本站最佳浏览方式为 分辨率 1024x768 IE 6.0(或更高版本的 IE浏览器)

go top