** 3.8 FLWOR ** ** 表达式 ** ** FLWOR Expressions ** ** **
XQuery 提供名为 FLWOR 表达式的特性,支持迭代及变量与中间结果的绑定。这类表达式对连接 2 个或多个文档的计算和重构数据往往有用。名称 FLWOR 发“ flower ”的音,暗示关键字 for , let , where , order by , 和 return .
[28]
|
_ FLWORExpr _
|
::=
|
( _ ForClause _ | _ LetClause _ )+ _ WhereClause _ ? _ OrderByClause _ ? "return" _ ExprSingle _
---|---|---|---
[29]
|
_ ForClause _
|
::=
|
"for" "$" _ VarName _ _ TypeDeclaration _ ? _ PositionalVar _ ? "in" _ ExprSingle _ ("," "$" _ VarName _ _ TypeDeclaration _ ? _ PositionalVar _ ? "in" _ ExprSingle _ )*
[31]
|
_ LetClause _
|
::=
|
"let" "$" _ VarName _ _ TypeDeclaration _ ? ":=" _ ExprSingle _ ("," "$" _ VarName _ _ TypeDeclaration _ ? ":=" _ ExprSingle _ )*
[109]
|
_ TypeDeclaration _
|
::=
|
"as" _ SequenceType _
[30]
|
_ PositionalVar _
|
::=
|
"at" "$" _ VarName _
[32]
|
_ WhereClause _
|
::=
|
"where" Expr
[33]
|
_ OrderByClause _
|
::=
|
("order" "by" | "stable" "order" "by") _ OrderSpecList _
[34]
|
_ OrderSpecList _
|
::=
|
_ OrderSpec _ ("," _ OrderSpec _ )*
[35]
|
_ OrderSpec _
|
::=
|
_ ExprSingle _ _ OrderModifier _
[36]
|
_ OrderModifier _
|
::=
|
("ascending" | "descending")? (("empty" "greatest") | ("empty" "least"))? ("collation" _ StringLiteral _ )?
FLWOR 表达式中的 for 和 let 子句生成一个绑定变量的元组的有序序列,称为 元组流 ( ** tuple stream ** )。可选的 where 子句用来过滤元组流,保留某些元组并删除其他的。可选子句 order by 可用来记录元组流。 return 子句构造 FLWOR 表达式的结果。 return 子句在 where 子句过滤后,使用在相应元组中绑定的变量为每一个元组流中的元组计算一次。 FLWOR 表达式的结果是一个包含这些计算的连接结果的有序序列。
下面是一个 FLWOR 表达式的例子,包含了所有可能的子句。 for 子句对输入文档中所有部门( department )进行迭代,将变量 $d 依次与每个部门编号进行绑定。对每个 $d 的绑定, let 子句将 $e 变量与给出部门的从另一个输入文档中选定的所有雇员( employees )绑定。 For 子句 和 let 子句的结果是一个元组流,其中每个元组包含一对 $d 和 $e 的绑定( $d 与部门编号绑定, $e 与那个部门中一组雇员绑定)。 where 子句过滤元组流,保留那些表示部门至少有十个雇员的绑定对( binding-pairs )。 order by 子句按照部门中雇员平均薪水的降序排序继续存在的元组。 return 子句为每个继续存在的元组构造一个新的元素 big-dept 包含部门编号、职员总数和平均薪水。
for $d in fn:doc("depts.xml")//deptno
let $e := fn:doc("emps.xml")//emp[deptno = $d]
where fn:count($e) >= 10
order by fn:avg($e/salary) descending
return
1<big-dept>
2
3{
4
5$d,
6
7<headcount>{fn:count($e)}</headcount>,
8
9<avgsal>{fn:avg($e/salary)}</avgsal>
10
11}
12
13</big-dept>
下面有 FLOWOR 表达式中的子句更多的说明。
** 3.8.1 For ** ** 和 ** ** Let ** ** 子句 ** ** For and Let Clauses **
FLWOR 表达式中 for 和 let 子句的用途是产生一个元组流,其中每个元组包含一到多个绑定变量。
最简单的 for 子句的例子包含一个变量和一个关联的表达式。我们称表达式的值为 输入序列 ( ** input sequence ** )。 for 子句迭代输入序列中的数据项,依次将变量与每个数据项绑定。如果排序模式( _ ordering mode _ )为 ordered ,则变量绑定的结果序列按照输入序列的值的次序排序;否则,变量绑定的次序为实现相关的( _ implementation-dependent _ )。
一个 for 子句也可能