XQuery xml query 是一种专门用于xml半结构化数据的查询语言,是W3C的推荐的标准语言。
XQuery是有一些SQL专家制定的,基本语法与sql语句非常相似。比xslt更加简单。
FLOWR语句与select语句相对应,完成对xml数据的查询,筛选和排序。FLOWR是指FOR,LET,WHERE,ORDERBY,RETURN五种语句。其中可以使用XPATH路径表达式以及xpath中的内置函数,各种自定义的函数,和命名空间。
for子句:
for $b in doc("bib-demo1.xml")/bib/book
for。。。in。。。相当与sql中的select。。。from。 $variable_name 表示声明一个变量,然后在 in ...的范围内进行循环遍历取值赋值给变量,然后进行之后的操作。 in后跟的是一个xpath的表达式, doc("...")表示文本文档,是xpath中的内置函数。
LET子句:
let $i as xs:integer := 100
相当与sql中的DECLARE和SET语句,声明一个变量并给其赋予一个初值。as后接数据的类型,一般在xs命名空间中的基础类型。 :=表示赋值。
WHERE语句:
where $b/author/last="Stevens"
相当与sql中的where语句。 判断式的前半部分为一个xpath表达式,后半部分为判断的值。若使用一个值即xpath作为操作数进行判断,若为空序列返回false,若序列第一个项为节点则返回true,若序列只含有一个单元子,若类型为xs:boolean,直接返回;若为xs:string等,则长度为0返回false,否则返回true;若为数值类型,则为0返回false,其他为true。
ORDERBY语句:
order by $a/last, $a/first descending
进行排序,缺省为ascending。还可以设置为descending。可以设置多个排序标准,首先按照第一个标准进行排序,对于相同的情况时,在按照后续的标准进行排序。
RETURN语句:
输出语句。在整个语句中,为每一个结果集中的每一项进行一次输出。可以进行如何文本格式的输出。
返回元素:
return {$salary}
return element income {$salary}
return
return element person { attribute gender {$i},$j}
{}大括号内的值为计算的值,可以在任何地方使用,包括引号内。。。
some $s in $S satisfies $s/C
exists($S[C])
every $s in $S satisfies not(C)
not(some $s in $S satisfies C)
element gender {if (node-name($node) cast as xs:string="husband") then "male" else "female"}
typeswitch($customer/billing-address)
case $a as element(*, USAddress) return $a/state
default return "unknown"
declare function HelloWorld() as xs:string
return "Hello World!"
列出2005-12-24日从North Pole出发的所有航班(dataQ1.xquery),将结果按照flightId进行排序输出;
{
for $p in doc("Data.xml")/doc/Flight
where $p/source = "NPL" and $p/date = "2005-12-24"
order by $p/flightId
return $p
}
declare function local:getFlights(
$pa as xs:string,
$pb as xs:string
)
as element()*
{
for $i in doc("Data.xml")/doc/Flight[contains(string(),$pa)][contains(string(),$pb)]
return
{ string($i/@flightId) }
};
{
for $a in doc("Data.xml")/doc/Airport
for $b in $a/following-sibling::Airport
where (doc("Data.xml")/doc/Flight[contains(string(),$a/@airId)][contains(string(),$b/@airId)])
return
{if ($a/@airId > $b/@airId) then string($b/@airId) else string($a/@airId) }
{if ($a/@airId > $b/@airId) then string($a/@airId) else string($b/@airId) }
{local:getFlights(string($a/@airId),string($b/@airId))}
}
这里要使用函数进行嵌套查询。。。element()后的*表示其可以返回多个元素,而在参数中也可以写成 $pa as xs:string? 表示参数可以使用也可以不使用。
按照2005-12-24日机场繁忙程度(计算进出旅客总数)列出机场(忽略没有旅客进出的机场)、以及其进出旅客总数(dataQ3.xquery);
declare function local:getFlight()
as element()*
{
for $a in doc("Data.xml")/doc/Reservation[./date = "2005-12-24"]
for $b in doc("Data.xml")/doc/Flight
where $b/@flightId = $a/flightRef
return $b
};
declare function local:getNum()
as element()*
{
for $i in doc("Data.xml")/doc/Airport
return
{$i}
{count(local:getFlight()[./source=$i/@airId]) + count(local:getFlight()[./destination=$i/@airId])}
};
{
(:仔细观察了Data后,这里只有4个乘客啊,难道就使用这4个乘客进行计数,其他所有的飞机上都没有人?:)
for $x in local:getNum()[./passNum > 0]
order by $x/passNum
return $x
}
函数中如果返回的是一个集合,则可以直接使用for对其中元素进行遍历,而且也可以直接加【】进行判断xpath的判定。
查询所有乘客去得最多的前三名目的地(dataQ4.xquery)
declare function local:getFlight()
as element()*
{
for $a in doc("Data.xml")/doc/Reservation[./date = "2005-12-24"]
for $b in doc("Data.xml")/doc/Flight
where $b/@flightId = $a/flightRef
return $b
};
declare function local:getNum()
as element()*
{
for $i in doc("Data.xml")/doc/Airport
return
{$i}
{count(local:getFlight()[./destination=$i/@airId])}
};
declare function local:get3Airport() as element()*
{
for $x in local:getNum()
order by $x/passNum descending
return $x
};
{
(:仍然使用这4个人来当做所有游客:)
for $y in local:get3Airport()[position()<4]
return {$y/Airport/name}
}
那个w3c上的栗子是在逗吗?坑我半天,蛋疼。