XQuery 1.0:XML查询语言 工作草案-3-3

TransWiki - W3CHINA.ORG开放翻译计划(OTP)

摘要_文档状态_目录 第1节 第2节 3.1~3.3节 3.4~3.6节 3.7节 3.8~3.13节 第4节 附录A 附录B,C,D 附录E,F,G,H,I


目录

3.8 FLWOR Expressions FLWOR表达式

XQuery provides a feature called a FLWOR expression that supports iteration and binding of variables to intermediate results. This kind of expression is often useful for computing joins between two or more documents and for restructuring data. The name FLWOR, pronounced "flower", is suggested by the keywords for, let, where, order by, and return.

XQuery提供名为FLWOR表达式的特性,支持迭代及变量与中间结果的绑定。这类表达式对连接2个或多个文档的计算和重构数据往往有用。名称FLWOR发“flower”的音,暗示关键字for, let, where, order by, 和 return。












[28]    FLWORExpr (http://www.w3.org/TR/2004/WD-xquery-20040723/#prod-xquery-FLWORExpr)    ::=    (ForClause (http://www.w3.org/TR/2004/WD-xquery-20040723/#doc-xquery-ForClause) | LetClause (http://www.w3.org/TR/2004/WD-xquery-20040723/#doc-xquery-LetClause))+ WhereClause (http://www.w3.org/TR/2004/WD-xquery-20040723/#doc-xquery-WhereClause)? OrderByClause (http://www.w3.org/TR/2004/WD-xquery-20040723/#doc-xquery-OrderByClause)? "return" ExprSingle (http://www.w3.org/TR/2004/WD-xquery-20040723/#doc-xquery-ExprSingle)
[29]    ForClause (http://www.w3.org/TR/2004/WD-xquery-20040723/#prod-xquery-ForClause)    ::=    "for" "$" VarName (http://www.w3.org/TR/2004/WD-xquery-20040723/#doc-xquery-VarName) TypeDeclaration (http://www.w3.org/TR/2004/WD-xquery-20040723/#doc-xquery-TypeDeclaration)? PositionalVar (http://www.w3.org/TR/2004/WD-xquery-20040723/#doc-xquery-PositionalVar)? "in" ExprSingle (http://www.w3.org/TR/2004/WD-xquery-20040723/#doc-xquery-ExprSingle) ("," "$" VarName (http://www.w3.org/TR/2004/WD-xquery-20040723/#doc-xquery-VarName) TypeDeclaration (http://www.w3.org/TR/2004/WD-xquery-20040723/#doc-xquery-TypeDeclaration)? PositionalVar (http://www.w3.org/TR/2004/WD-xquery-20040723/#doc-xquery-PositionalVar)? "in" ExprSingle (http://www.w3.org/TR/2004/WD-xquery-20040723/#doc-xquery-ExprSingle))*
[31]    LetClause (http://www.w3.org/TR/2004/WD-xquery-20040723/#prod-xquery-LetClause)    ::=    "let" "$" VarName (http://www.w3.org/TR/2004/WD-xquery-20040723/#doc-xquery-VarName) TypeDeclaration (http://www.w3.org/TR/2004/WD-xquery-20040723/#doc-xquery-TypeDeclaration)? ":=" ExprSingle (http://www.w3.org/TR/2004/WD-xquery-20040723/#doc-xquery-ExprSingle) ("," "$" VarName (http://www.w3.org/TR/2004/WD-xquery-20040723/#doc-xquery-VarName) TypeDeclaration (http://www.w3.org/TR/2004/WD-xquery-20040723/#doc-xquery-TypeDeclaration)? ":=" ExprSingle (http://www.w3.org/TR/2004/WD-xquery-20040723/#doc-xquery-ExprSingle))*
[109]    TypeDeclaration (http://www.w3.org/TR/2004/WD-xquery-20040723/#prod-xquery-TypeDeclaration)    ::=    "as" SequenceType (http://www.w3.org/TR/2004/WD-xquery-20040723/#doc-xquery-SequenceType)
[30]    PositionalVar (http://www.w3.org/TR/2004/WD-xquery-20040723/#prod-xquery-PositionalVar)    ::=    "at" "$" VarName (http://www.w3.org/TR/2004/WD-xquery-20040723/#doc-xquery-VarName)
[32]    WhereClause (http://www.w3.org/TR/2004/WD-xquery-20040723/#prod-xquery-WhereClause)    ::=    "where" Expr (http://www.w3.org/TR/2004/WD-xquery-20040723/#doc-xquery-Expr)
[33]    OrderByClause (http://www.w3.org/TR/2004/WD-xquery-20040723/#prod-xquery-OrderByClause)    ::=    ("order" "by" | "stable" "order" "by") OrderSpecList (http://www.w3.org/TR/2004/WD-xquery-20040723/#doc-xquery-OrderSpecList)
[34]    OrderSpecList (http://www.w3.org/TR/2004/WD-xquery-20040723/#prod-xquery-OrderSpecList)    ::=    OrderSpec (http://www.w3.org/TR/2004/WD-xquery-20040723/#doc-xquery-OrderSpec) ("," OrderSpec (http://www.w3.org/TR/2004/WD-xquery-20040723/#doc-xquery-OrderSpec))*
[35]    OrderSpec (http://www.w3.org/TR/2004/WD-xquery-20040723/#prod-xquery-OrderSpec)    ::=    ExprSingle (http://www.w3.org/TR/2004/WD-xquery-20040723/#doc-xquery-ExprSingle) OrderModifier (http://www.w3.org/TR/2004/WD-xquery-20040723/#doc-xquery-OrderModifier)
[36]    OrderModifier (http://www.w3.org/TR/2004/WD-xquery-20040723/#prod-xquery-OrderModifier)    ::=    ("ascending" | "descending")? (("empty" "greatest") | ("empty" "least"))? ("collation" StringLiteral (http://www.w3.org/TR/2004/WD-xquery-20040723/#doc-xquery-StringLiteral))?

The for and let clauses in a FLWOR expression generate an ordered sequence of tuples of bound variables, called the tuple stream. The optional where clause serves to filter the tuple stream, retaining some tuples and discarding others. The optional order by clause can be used to reorder the tuple stream. The return clause constructs the result of the FLWOR expression. The return clause is evaluated once for every tuple in the tuple stream, after filtering by the where clause, using the variable bindings in the respective tuples. The result of the FLWOR expression is an ordered sequence containing the concatenated results of these evaluations.

FLWOR表达式中的for 和 let 子句生成一个绑定变量的元组的有序序列,称为元组流(tuple stream)。可选的where子句用来过滤元组流,保留某些元组并删除其他的。可选子句order by可用来记录元组流。return子句构造FLWOR表达式的结果。return子句在where子句过滤后,使用在相应元组中绑定的变量为每一个元组流中的元组计算一次。FLWOR表达式的结果是一个包含这些计算的连接结果的有序序列。

The following example of a FLWOR expression includes all of the possible clauses. The for clause iterates over all the departments in an input document, binding the variable $d to each department number in turn. For each binding of $d, the let clause binds variable $e to all the employees in the given department, selected from another input document. The result of the for and let clauses is a tuple stream in which each tuple contains a pair of bindings for $d and $e ($d is bound to a department number and $e is bound to a set of employees in that department). The where clause filters the tuple stream by keeping only those binding-pairs that represent departments having at least ten employees. The order by clause orders the surviving tuples in descending order by the average salary of the employees in the department. The return clause constructs a new big-dept element for each surviving tuple, containing the department number, headcount, and average salary.

下面是一个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

   <big-dept>
{
$d,
<headcount>{fn:count($e)}</headcount>,
<avgsal>{fn:avg($e/salary)}</avgsal>
}
</big-dept>


The clauses in a FLWOR expression are described in more detail below.

下面有FLOWOR表达式中的子句更多的说明。

3.8.1 For and Let Clauses For和Let子句

The purpose of the for and let clauses in a FLWOR expression is to produce a tuple stream in which each tuple consists of one or more bound variables.

FLWOR表达式中for 和 let子句的用途是产生一个元组流,其中每个元组包含一到多个绑定变量。

The simplest example of a for clause contains one variable and an associated expression. We will refer to the value of the expression as the input sequence. The for clause iterates over the items in the input sequence, binding the variable to each item in turn. If ordering mode (http://www.w3.org/TR/2004/WD-xquery-20040723/#dt-ordering-mode) is ordered, the resulting sequence of variable bindings is ordered according to the order of values in the input sequence; otherwise the ordering of the variable bindings is implementation-dependent (http://www.w3.org/TR/2004/WD-xquery-20040723/#dt-implementation-dependent).

最简单的for子句的例子包含一个变量和一个关联的表达式。我们称表达式的值为输入序列(input sequence)。for子句迭代输入序列中的数据项,依次将变量与每个数据项绑定。如果排序模式(ordering mode)为ordered,则变量绑定的结果序列按照输入序列的值的次序排序;否则,变量绑定的次序为实现相关的(implementation-dependent)。

A for clause may also contain multiple variables, each with an associated expression whose value is the input sequence for that variable. In this case, the for clause iterates each variable over its input sequence. The resulting tuple stream contains one tuple for each combination of values in the Cartesian product of the input sequences. If ordering mode (http://www.w3.org/TR/2004/WD-xquery-20040723/#dt-ordering-mode) is ordered, the order of the tuple stream is determined primarily by the order of the input sequence of the leftmost variable, and secondarily by the input sequences of the other variables, working from left to right. Otherwise, the ordering of the variable bindings is implementation-dependent (http://www.w3.org/TR/2004/WD-xquery-20040723/#dt-implementation-dependent).

一个for子句也可能包含多个变量,每个变量有一个关联表达式,其值为那个变量的输入序列(input sequence)。在这种情况下,for子句迭代每个变量到其输入序列。结果元组流对每一个值与输入序列的笛卡儿乘积的组合包含一个元组。如果排序模式(ordering mode)为ordered,则元组流的次序主要由最左边的变量的输入序列的次序决定,再从左到右由其他变量的输入序列决定。否则,变量绑定的次序为实现相关的(implementation-dependent)。

A let clause may also contain one or more variables, each with an associated expression. Unlike a for clause, however, a let clause binds each variable to the result of its associated expression, without iteration. The variable bindings generated by let clauses are added to the binding tuples generated by the for clauses. If there are no for clauses, the let clauses generate one tuple containing all the variable bindings.

一个let子句也可能包含一个或多个变量,每个变量有一个关联表达式。然而,与for子句不同的是,一个let子句将每个变量与其关联表达式的结果绑定,并不迭代。由let子句生成的变量绑定加到由for子句生成的绑定元组上。如果没有for子句,let子句生成一个包含所有变量绑定的元组。

Although for and let clauses both bind variables, the manner in which variables are bound is quite different, as illustrated by the following examples. The first example uses a let clause:

虽然for子句和let子句都绑定变量,但变量绑定的方式完全不同,与下例说明的一样。第一个例子使用了一个let子句:


let $s := (<one/>, <two/>, <three/>)
return <out>{$s}</out>


The variable $s is bound to the result of the expression (<one/>, <two/>, <three/>). Since there are no for clauses, the let clause generates one tuple that contains the binding of $s. The return clause is invoked for this tuple, creating the following output:

变量$s与表达式(<one/>,<two/>,<three/>)的结果绑定。由于没有for子句,let子句生成一个包含$s的绑定的元组。return子句调用这个元组,创建下列输出:


<out>

   <one/>
<two/>
<three/>

</out>


The next example is a similar query that contains a for clause instead of a let clause:

下一个例子是一个简单的查询,包含一个for子句而不是let子句:


for $s in (<one/>, <two/>, <three/>)
return <out>{$s}</out>


In this example, the variable $s iterates over the given expression. If ordering mode (http://www.w3.org/TR/2004/WD-xquery-20040723/#dt-ordering-mode) is ordered, $s is first bound to <one/>, then to <two/>, and finally to <three/>. One tuple is generated for each of these bindings, and the return clause is invoked for each tuple, creating the following output:

本例中,变量$s迭代给定的表达式。如果排序模式(ordering mode)为ordered,$s先和<one/>绑定,然后和<two/>,最后和<three/>绑定。这些绑定每个产生一个元组,return子句调用每个元组,创建下面的输出:

<out>

   <one/>

</out>
<out>

   <two/>

</out>
<out>

   <three/>

</out>


The following example illustrates how binding tuples are generated by a for clause that contains multiple variables when ordering mode (http://www.w3.org/TR/2004/WD-xquery-20040723/#dt-ordering-mode) is ordered.

下例说明当排序模式(ordering mode)为ordered时,绑定元组如何由一个包含多个变量的for子句生成。

for $i in (1, 2), $j in (3, 4)


The tuple stream generated by the above for clause is as follows:

由以上for子句生成的元组流如下:

($i = 1, $j = 3)
($i = 1, $j = 4)
($i = 2, $j = 3)
($i = 2, $j = 4)


If ordering mode (http://www.w3.org/TR/2004/WD-xquery-20040723/#dt-ordering-mode) were unordered, the for clause in the above example would generate the same tuple stream but the order of the tuples would be implementation-dependent (http://www.w3.org/TR/2004/WD-xquery-20040723/#dt-implementation-dependent).

如果排序模式(ordering mode)为unordered,上例中的for子句将生成同样的元组流,但是元组次序将为实现相关的(implementation-dependent)。

The scope of a variable bound in a for or let clause comprises all subexpressions of the containing FLWOR expression that appear after the variable binding. The scope does not include the expression to which the variable is bound. The following example illustrates how for and let clauses may reference variables that were bound in earlier clauses in the same FLWOR expression:

for子句或者let子句中变量绑定的作用域,包括所属FLWOR表达式中变量绑定后的所有子表达式。作用域不包括变量所绑定的表达式。下例说明for和let子句会怎样引用同一个FLWOR表达式里较早的子句中绑定的变量:

for $x in $w
let $y := f($x)
for $z in g($x, $y)
return h($x, $y, $z)


Each variable bound in a for or let clause may have an optional type declaration, which is a type declared using the syntax in 2.4.3 SequenceType Syntax. If the type of a value bound to the variable does not match the declared type according to the rules for SequenceType matching (http://www.w3.org/TR/2004/WD-xquery-20040723/#dt-sequencetype-matching), a type error (http://www.w3.org/TR/2004/WD-xquery-20040723/#dt-type-error) is raised.[err:XP0004 (http://www.w3.org/TR/2004/WD-xquery-20040723/#ERRXP0004)][err:XP0006 (http://www.w3.org/TR/2004/WD-xquery-20040723/#ERRXP0006)] For example, the following expression raises a type error (http://www.w3.org/TR/2004/WD-xquery-20040723/#dt-type-error) because the variable $salary has a type declaration that is not satisfied by the value that is bound to the variable:

每个for或者let子句中绑定的变量会有一个可选的类型声明(type declaration),这是一个使用2.4.3 SequenceType Syntax中的语法声明的类型。依照序列类型匹配(SequenceType matching)规则,如果绑定到变量的值的类型与声明的类型不匹配,将引发一个类型错误(type error)。 [err:XP0004][err:XP0006] 例如,下面的表达式引发一个类型错误(type error),因为变量$salary有一个类型声明没有被与变量绑定的值满足:

let $salary as xs:decimal := "cat"
return $salary * 2


Each variable bound in a for clause may have an associated positional variable that is bound at the same time. The name of the positional variable is preceded by the keyword at. The positional variable always has an implied type of xs:integer. As a variable iterates over the items in its input sequence, its positional variable iterates over the integers that represent the ordinal positions of those items in the input sequence, starting with 1.
Positional variables are illustrated by the following for clause:

for子句中绑定的每一个变量会被同时绑定一个相关的位置变量(positional variable)。位置变量的的名字前面是关键字at。位置变量总是有一个隐含类型xs:integer。当一个变量迭代输入序列中的数据项时,其位置变量迭代输入序列中代表数据项次序位置的整数,从1开始。
下面的for子句说明位置变量:

for $car at $i in ("Ford", "Chevy"),

    $pet at $j in ("Cat", "Dog")


If ordering mode (http://www.w3.org/TR/2004/WD-xquery-20040723/#dt-ordering-mode) is ordered, the tuple stream generated by the above for clause is as follows:

如果排序模式(ordering mode)为ordered,由以上for子句生成的元组流如下:

($i = 1, $car = "Ford", $j = 1, $pet = "Cat")
($i = 1, $car = "Ford", $j = 2, $pet = "Dog")
($i = 2, $car = "Chevy", $j = 1, $pet = "Cat")
($i = 2, $car = "Chevy", $j = 2, $pet = "Dog")


If ordering mode (http://www.w3.org/TR/2004/WD-xquery-20040723/#dt-ordering-mode) is unordered, the resulting tuple stream contains the same tuples, in implementation-dependent (http://www.w3.org/TR/2004/WD-xquery-20040723/#dt-implementation-dependent) order.

如果排序模式(ordering mode)为unordered,结果元组流以实现相关(implementation-dependent)的次序包含同样的元组。

3.8.2 Where Clause Where子句

The optional where clause serves as a filter for the tuples of variable bindings generated by the for and let clauses. The expression in the where clause, called the where-expression, is evaluated once for each of these tuples. If the effective boolean value (http://www.w3.org/TR/2004/WD-xquery-20040723/#dt-ebv) of the where-expression is true, the tuple is retained and its variable bindings are used in an execution of the return clause. If the effective boolean value (http://www.w3.org/TR/2004/WD-xquery-20040723/#dt-ebv) of the where-expression is false, the tuple is discarded. The effective boolean value (http://www.w3.org/TR/2004/WD-xquery-20040723/#dt-ebv) of an expression is defined in 2.3.3 Effective Boolean Value.

可选的where子句为for和let子句生成的变量绑定的元组做过滤器服务。where子句中的表达式称为where表达式(where-expression),为其中每个元组计算一次。如果where表达式的有效布尔值(effective boolean value)为true,元组被保留并且其变量绑定被用于一个return子句的执行。如果where-expression的有效布尔值(effective boolean value)为false,则元组被删除。表达式的有效布尔值(effective boolean value)在2.3.3 Effective Boolean Value中定义。

The following expression illustrates how a where clause might be applied to a positional variable in order to perform sampling on an input sequence. This expression approximates the average value in a sequence by sampling one value out of each one hundred input values.

下面的表达式说明where子句会如何被应用于位置变量(positional variable),以完成一个输入序列的采样。这个表达式通过从每一百个输入值中抽取一个样品的方法,来约计一个序列中的平均值。

fn:avg(for $x at $i in $inputvalues

    where $i mod 100 = 0   
return $x)


3.8.3 Order By and Return Clauses Order By和Return子句

The return clause of a FLWOR expression is evaluated once for each tuple in the tuple stream, and the results of these evaluations are concatenated to form the result of the FLWOR expression.

FLWOR表达式的return 子句为元组流中的每一个元组计算一次,这些计算结果连接形成FLWOR表达式的结果。

If no order by clause is present, the order of the tuple stream is determined by the for and let clauses and by ordering mode (http://www.w3.org/TR/2004/WD-xquery-20040723/#dt-ordering-mode). If an order by clause is present, it reorders the tuples in the tuple stream into a new, value-based order. In either case, the resulting order determines the order in which the return clause is evaluated, once for each tuple, using the variable bindings in the respective tuples. Note that ordering mode (http://www.w3.org/TR/2004/WD-xquery-20040723/#dt-ordering-mode) has no effect on a FLWOR expression if an order by clause is present, since order by takes precedence over ordering mode (http://www.w3.org/TR/2004/WD-xquery-20040723/#dt-ordering-mode).

如果没有order by子句,元组流的次序由for 和 let子句根据排序模式(ordering mode)决定。如果存在order by子句,它以一个新的,基于值的次序排序元组流中的元组。不论发生哪种情况,由此得到的次序确定return子句使用相应元组中的变量绑定每次每个元组计算的次序。注意如果有order by子句存在,则排序模式(ordering mode)在FLWOR表达式中无效,因为的order by优先级比排序模式(ordering mode)高。

An order by clause contains one or more ordering specifications, called orderspecs (http://www.w3.org/TR/2004/WD-xquery-20040723/#doc-xquery-OrderSpec), as shown in the grammar above. For each tuple in the tuple stream, the orderspecs are evaluated, using the variable bindings in that tuple. The relative order of two tuples is determined by comparing the values of their orderspecs, working from left to right until a pair of unequal values is encountered. If the values to be compared are strings, the orderspec may indicate the collation to be used (if no collation is specified, the default collation is used.)

正如上面语法中展示的那样,一个order by 子句包含一个或者多个排序规格说明,称为orderspecs。对于元组流中的每一个元组,使用元组中绑定的变量计算orderspec。两个元组的次序关系由他们orderspec的值比较决定,从左到右比较,直到遇到一对不等的值。如果进行比较的值是字符串,orderspec指出要使用的校对(collation)(如果没有指定校对,则使用默认的校对。)

The process of evaluating and comparing the orderspecs is based on the following rules:

计算和比较orderspec的过程基于下列规则:


Atomization (http://www.w3.org/TR/2004/WD-xquery-20040723/#dt-atomization) is applied to the result of the expression in each orderspec. If the result of atomization is neither a single atomic value nor an empty sequence, a type error (http://www.w3.org/TR/2004/WD-xquery-20040723/#dt-type-error) is raised.[err:XP0004 (http://www.w3.org/TR/2004/WD-xquery-20040723/#ERRXP0004)][err:XP0006 (http://www.w3.org/TR/2004/WD-xquery-20040723/#ERRXP0006)]

• 每个orderspec中表达式的结果被原子化(Atomization)。如果原子化的结果既不是一个单一的原子值,也不是一个空序列,将引发一个类型错误(type error)[err:XP0004][err:XP0006]。


If the value of an orderspec has the dynamic type xdt:untypedAtomic (such as character data in a schemaless document), it is cast to the type xs:string.

• 如果一个orderspec的值有一个动态类型xdt:untypedAtomic(比如一个无模式(schemaless)文档中的字符数据),它被指派为xs:string类型。

Note:
Consistently treating untyped values as strings enables the sorting process to begin without complete knowledge of the types of all the values to be sorted.

注意:
一贯地把无类型值当成字符串,会在缺少所有被排序值类型的完整知识时,开始排序过程。


All the orderspec values must be convertible to a common type by subtype substitution (http://www.w3.org/TR/2004/WD-xquery-20040723/#dt-subtype-substitution) and/or numeric type promotion (http://www.w3.org/TR/2004/WD-xquery-20040723/#dt-type-promotion). The ordering is performed in the least common type that has a gt operator. If two or more orderspec values are not convertible to a common type that has a gt operator, a type error (http://www.w3.org/TR/2004/WD-xquery-20040723/#dt-type-error) is raised. [err:XP0004 (http://www.w3.org/TR/2004/WD-xquery-20040723/#ERRXP0004)][err:XP0006 (http://www.w3.org/TR/2004/WD-xquery-20040723/#ERRXP0006)]

• 所有的orderspec类型必须是可被子类型代换(subtype substitution)和/或数值类型提升(type promotion)转换为公共类型的。排序以有运算符gt的最小公共类型执行。如果两个或者多个orderspec值没有转换为有运算符gt的公共类型,将引发一个类型错误(type error) [err:XP0004][err:XP0006]。


Example: The orderspec values include a value of type hatsize, which is derived from xs:integer, and a value of type shoesize, which is derived from xs:decimal. The least common type reachable by subtype substitution and numeric type promotion is xs:decimal.

o 例:orderspec值包含一个从xs:integer派生出的hatsize类型的值,和一个从xs:decimal派生出的shoesize类型的值。由子类型代换和数值类型提升可获得的最小的公共类型值为xs:decimal。


Example: The orderspec values include a value of type xs:string and a value of type xs:anyURI. Since these types have no common type reachable by subtype substitution and numeric type promotion, a type error is raised.

o 例:orderspec值包含一个xs:string类型的值和一个xs:anyURI类型的值。由于这些类型不能通过子类型代换和数值类型提升得到公共类型,所以引发一个类型错误。

When two orderspec values are compared to determine their relative position in the ordering sequence, the greater-than relationship is defined as follows:

当比较两个orderspec值以确定其在排序序列中的相对位置时,大于(greater-than)关系定义如下:


When the orderspec specifies empty least, a value W is considered to be greater-than a value V if one of the following is true:


V is an empty sequence and W is not an empty sequence.


V is NaN, and W is neither NaN nor an empty sequence.


No collation is specified, and W gt V is true.


A specific collation C is specified, and fn:compare(V, W, C) is less than zero.

• 当orderspec规定empty least时,如果下列条件之一为真,则认为值W大于(greater-than)值V:
o V为空序列,且W为非空序列。
o V为 NaN,且W既不是NaN也不是空序列。
o 未指定校对,且W gt V为真。
o 具体校对C被指定,且fn:compare(V, W, C) 小于零。


When the orderspec specifies empty greatest, a value W is considered to be greater-than a value V if one of the following is true:


W is an empty sequence and V is not an empty sequence.


W is NaN, and V is neither NaN nor an empty sequence.


No collation is specified, and W gt V is true.


A specific collation C is specified, and fn:compare(V, W, C) is less than zero.

• 当orderspec规定empty greatest时,如果下列条件之一为真,则认为值W大于(greater-than)值V:
o W 为空序列,且V为非空序列。
o W为 NaN,且V既不是NaN也不是空序列。
o 未指定校对,且W gt V为真。
o 具体校对C被指定,且fn:compare(V, W, C) 小于零。


When the orderspec specifies neither empty least nor empty greatest, it is implementation-defined (http://www.w3.org/TR/2004/WD-xquery-20040723/#dt-implementation-defined) whether the rules for empty least or empty greatest are used.

• 当orderspec既未确定empty least也未确定empty greatest时,是否使用empty least或者empty greatest规则,是实现相关的(implementation-defined)。

If T1 and T2 are two tuples in the tuple stream, and V1 and V2 are the first pair of values encountered when evaluating their orderspecs from left to right for which one value is greater-than the other (as defined above), then:

如果T1和T2为元组流中的两个元组,且V1、V2是当从左到右计算它们的orderspec时,遇到的第一对一个大于(greater-than)另一个的值(如上述定义),那么:


If V1 is greater-than V2: If the orderspec specifies descending, then T1 precedes T2 in the tuple stream; otherwise, T2 precedes T1 in the tuple stream.

1. 如果V1大于(greater-than)V2: 如果orderspec指定降序(descending),则T1在元组流中的位置放在T2之前;否则,T2在元组流中的位置在T1之前。


If V2 is greater-than V1: If the orderspec specifies descending, then T2 precedes T1 in the tuple stream; otherwise, T1 precedes T2 in the tuple stream.

2. 如果V2大于(greater-than)V1: 如果orderspec指定降序(descending),则T2在元组流中的位置放在T1之前;否则,T1在元组流中的位置在T2之前。

If neither V1 nor V2 is greater-than the other for any pair of orderspecs for tuples T1 and T2, then:

如果对于元组T1和T2的任何一对orderspecs,V1和V2都不大于(greater-than)另一个,那么:


If stable is specified, the original order of T1 and T2 is preserved in the tuple stream.

1. 如果规定了 stable ,在元组流中保持T1和T2原始次序。


If stable is not specified, the order of T1 and T2 in the tuple stream is implementation-dependent (http://www.w3.org/TR/2004/WD-xquery-20040723/#dt-implementation-dependent).

2. 如果没有规定 stable ,则元组流中T1 和 T2的次序是实现相关的(implementation-dependent)。

An order by clause makes it easy to sort the result of a FLWOR expression, even if the sort key is not included in the result of the expression. For example, the following expression returns employee names in descending order by salary, without returning the actual salaries:

order by 子句使得对一个FLWOR表达式的结果进行分类很方便,即使分类关键词不包括在表达式结果中。例如,下面的表达式按照薪金降序返回雇员名,不返回具体的薪金:

for $e in $employees
order by $e/salary descending
return $e/name


The order by clause is the only facility provided by XQuery for specifying an order other than document order (http://www.w3.org/TR/2004/WD-xquery-20040723/#dt-document-order). Therefore, every query in which an order other than document order is required must contain a FLWOR expression, even though iteration would not otherwise be necessary. For example, a list of books with price less than 100 might be obtained by a simple path expression such as $books//book[price < 100]. But if these books are to be returned in alphabetic order by title, the query must be expressed as follows:

order by子句是XQuery提供的除了文档次序(document order)以外唯一的指定次序的功能。因此,即使并不需要迭代,每个除了文档次序以为要求排序的查询必须包含一个FLOWOR表达式。例如,一个价格少于100的书的列表可以简单的由如$books//book[price < 100]的路径表达式获得。但是如果这些书要以书名的字母次序返回,查询必须表示如下:

for $b in $books//book[price < 100]
order by $b/title
return $b


The following example illustrates an order by clause that uses several options. It causes a collection of books to be sorted in primary order by title, and in secondary descending order by price. A specific collation is specified for the title ordering, and in the ordering by price, books with no price are specified to occur last (as though they have the least possible price). Whenever two books with the same title and price occur, the keyword stable indicates that their input order is preserved.

下列例子说明一个使用若干选项的order by子句。它使得一个书的集合被主要以书名排序,其次以价格降序排序。一个具体的校对被指定给书名排序,而在价格排序中,规定没有价格的书最后出现(就像它们有可能的最小价格)。只要两个具有相同书名和价格的书出现,关键字表明它们的输入顺序将被保留。

for $b in $books//book
stable order by $b/title collation "eng-us",

   $b/price descending empty least

return $b


3.8.4 Example 实例

The following example illustrates how FLWOR expressions can be nested, and how ordering can be specified at multiple levels of an element hierarchy. The example query inverts a document hierarchy to transform a bibliography into an author list. The input bibliography is a list of books in which each book contains a list of authors. The example is based on the following input:

下例说明FLWOR表达式是如何嵌套的,以及在多级元素层次上如何指定次序关系。示例查询颠倒一个文档的层次,把一个书刊目录变换为一个作者列表。输入书目是一个书名列表,其中每个书包含一个作者列表。例子基于如下输入:

<bib>

  <book>
<title>TCP/IP Illustrated</title>
<author>Stevens</author>
<publisher>Addison-Wesley</publisher>
</book>
<book>
<title>Advanced Programming
in the Unix Environment</title>
<author>Stevens</author>
<publisher>Addison-Wesley</publisher>
</book>
<book>
<title>Data on the Web</title>
<author>Abiteboul</author>
<author>Buneman</author>
<author>Suciu</author>
</book>

</bib>


The following query transforms the input document into a list in which each author's name appears only once, followed by a list of titles of books written by that author. The fn:distinct-values function is used to eliminate duplicates (by value) from a list of author nodes. The author list, and the lists of books published by each author, are returned in alphabetic order using the default collation.

下面的查询将输入文本变换为一个列表,其中每个作者的名字只出现一次,随后是这个作者所著书名列表。函数fn:distinct-values用来从作者节点列表中删去重复(值)。作者列表和由每个作者出版的书目列表都使用默认的校对,以字母次序返回。

<authlist>

 {
for $a in fn:distinct-values($books//author)
order by $a
return
<author>
<name> {$a} </name>
<books>
{
for $b in $books//book[author = $a]
order by $b/title
return $b/title
}
</books>
</author>
}

</authlist>


The result of the above expression is as follows:

上面表达式的结果如下:

<authlist>

   <author>
<name>Abiteboul</name>
<books>
<title>Data on the Web</title>
</books>
</author>
<author>
<name>Buneman</name>
<books>
<title>Data on the Web</title>
</books>
</author>
<author>
<name>Stevens</name>
<books>
<title>TCP/IP Illustrated</title>
<title>Advanced Programming
in the Unix Environment</title>
</books>
</author>
<author>
<name>Suciu</name>
<books>
<title>Data on the Web</title>
</books>
</author>

</authlist>


3.9 Ordered and Unordered Expressions 有序和无序表达式




[81]    OrderedExpr (http://www.w3.org/TR/2004/WD-xquery-20040723/#prod-xquery-OrderedExpr)    ::=    "ordered" "{" Expr (http://www.w3.org/TR/2004/WD-xquery-20040723/#doc-xquery-Expr) "}"
[82]    UnorderedExpr (http://www.w3.org/TR/2004/WD-xquery-20040723/#prod-xquery-UnorderedExpr)    ::=    "unordered" "{" Expr (http://www.w3.org/TR/2004/WD-xquery-20040723/#doc-xquery-Expr) "}"

The purpose of ordered and unordered expressions is to set the ordering mode (http://www.w3.org/TR/2004/WD-xquery-20040723/#dt-ordering-mode) in the static context (http://www.w3.org/TR/2004/WD-xquery-20040723/#dt-static-context) to ordered or unordered for a certain region in a query. The specified ordering mode applies to the expression nested inside the curly braces. For expressions where the ordering of the result is not significant, a performance advantage may be realized by setting the ordering mode to unordered, thereby granting the system flexibility to return the result in the order that it finds most efficient.

有序(ordered)和无序(unordered)表达式的目的是在一个查询的特定范围设置静态语境(static context)中排序模式(ordering mode)为有序的(ordered)或者无序的(unordered)。指定的排序模式应用于嵌套于花括号内的表达式。对于其结果的排序不重要的表达式,可以将排序模式设置为unordered来实现一项性能上的优越性,从而授权系统以最有效的次序灵活地返回结果。

Ordering mode (http://www.w3.org/TR/2004/WD-xquery-20040723/#dt-ordering-mode) affects the behavior of path expressions, union, intersect, and except expressions, and FLWOR expressions that have no order by clause. If ordering mode is ordered, node sequences returned by path, union, intersect, and except expressions are in document order (http://www.w3.org/TR/2004/WD-xquery-20040723/#dt-document-order); otherwise the order of these return sequences is implementation-dependent (http://www.w3.org/TR/2004/WD-xquery-20040723/#dt-implementation-dependent). The effect of ordering mode on FLWOR expressions is described in 3.8 FLWOR Expressions. Ordering mode has no effect on duplicate elimination.

排序模式(Ordering mode)影响路径表达式、union、 intersect和except表达式以及没有order by子句的FLWOR表达式的运行方式。如果排序模式为有序的(ordered),则由路径、union、intersect和except表达式返回的节点序列为文档次序(document order);否则这些返回序列的次序是实现相关的(implementation-dependent)。排序模式对于FLWOR表达式的作用在3.8 FLWOR Expressions中说明。排序模式对重复的删除没有作用。

Note:
In a region of the query where ordering mode is unordered, certain functions that depend on the ordering of node sequences may return nondeterministic results. These functions include fn:position, fn:last, fn:index-of, fn:insert-before, fn:remove, fn:reverse, and fn:subsequence. Also, within a path expression in an unordered region, numeric predicates are nondeterministic. For example, in an ordered region, the path expression //a/b[5] will return the fifth qualifying b-element in document order (http://www.w3.org/TR/2004/WD-xquery-20040723/#dt-document-order). In an unordered region, the same expression will return an implementation-dependent (http://www.w3.org/TR/2004/WD-xquery-20040723/#dt-implementation-dependent) qualifying b-element.

注意:
在一个排序模式为unordered的查询区域中,某些依赖节点次序的函数会返回不确定的结果。这些函数包括fn:position, fn:last, fn:index-of, fn:insert-before, fn:remove, fn:reverse, 和 fn:subsequence。在一个无序的区域中,一个路径表达式中的数值谓词也是不确定的。例如,在一个有序区域中,路径表达式//a/b[5]将以文档次序(document order)返回第五个限定的b元素(b-element)。在一个无序区域中,同样的表达式将返回一个实现相关的(implementation-dependent)限定的b元素(b-element)。

The use of an unordered expression is illustrated by the following example, which joins together two documents named parts.xml and suppliers.xml. The example returns the part numbers of red parts, paired with the supplier numbers of suppliers who supply these parts. If an unordered expression were not used, the resulting list of (part number, supplier number) pairs would be required to have an ordering that is controlled primarily by the document order (http://www.w3.org/TR/2004/WD-xquery-20040723/#dt-document-order) of parts.xml and secondarily by the document order (http://www.w3.org/TR/2004/WD-xquery-20040723/#dt-document-order) of suppliers.xml. However, this might not be the most efficient way to process the query if the ordering of the result is not important. An XQuery implementation might be able to process the query more efficiently by using an index to find the red parts, or by using suppliers.xml rather than parts.xml to control the primary ordering of the result. The unordered expression gives the query evaluator freedom to make these kinds of optimizations.

一个无序的(unordered)表达式的使用通过下例说明,这个例子将两个名为parts.xml和suppliers.xml的文档联结在一起。例子返回红色零件的数目,和提供这些零件的供方编号。如果没有使用无序的(unordered)表达式,则要求结果(零件数、供方编号)对列表有个一个顺序,这个顺序主要由parts.xml的文档顺序(document order)控制,其次由suppliers.xml的文档顺序(document order)控制。但是如果结果的排序不重要,这可能不是处理查询最有效的方法。一个XQuery实现可以使用索引来查找红色零件,或者使用suppliers.xml控制结果的主要次序而不是parts.xml,来更有效的处理查询。无序(unordered)表达式给予了查询求值程序使用这类优化的自由。

unordered {

  for $p in fn:doc("parts.xml")//part[color = "Red"],
$s in fn:doc("suppliers.xml")//supplier
where $p/suppno = $s/suppno
return
<ps>
{ $p/partno, $s/suppno }
</ps>

}


In addition to ordered and unordered expressions, XQuery provides a function named fn:unordered that operates on any sequence of items and returns the same sequence in a nondeterministic order. A call to the fn:unordered function may be thought of as giving permission for the argument expression to be materialized in whatever order the system finds most efficient. The fn:unordered function differs from an unordered expression in the following ways:

除了ordered表达式和unordered表达式,XQuery提供了一个名为fn:unordered的函数,它作用于数据项的任一序列并以不确定的次序返回同一个序列。对fn:unordered函数的调用被认为是允许参数表达式以任意系统认为最有效的次序来实现。fn:unordered函数与unordered表达式有以下不同:


The fn:unordered function relaxes ordering only for the sequence that is its immediate operand, whereas an unordered expression sets the ordering mode (http://www.w3.org/TR/2004/WD-xquery-20040723/#dt-ordering-mode) for its operand expression and all nested expressions.

• 函数fn:unordered 只为是其紧靠着的操作对象的序列排序,而unordered表达式为其操作对象表达式及其所有嵌套表达式设置排序模式(ordering mode)。


The fn:unordered function can operate on any sequence, whereas an unordered expression affects the ordering only of node sequences (not sequences of atomic values).

• 函数fn:unordered能对任一序列起作用,而unordered表达式只影响节点序列(不是原子值的序列)的次序。

3.10 Conditional Expressions 条件表达式

XQuery supports a conditional expression based on the keywords if, then, and else.

XQuery支持基于关键字if, then, 和 else的条件表达式。



[40]    IfExpr (http://www.w3.org/TR/2004/WD-xquery-20040723/#prod-xquery-IfExpr)    ::=    "if" "(" Expr (http://www.w3.org/TR/2004/WD-xquery-20040723/#doc-xquery-Expr) ")" "then" ExprSingle (http://www.w3.org/TR/2004/WD-xquery-20040723/#doc-xquery-ExprSingle) "else" ExprSingle (http://www.w3.org/TR/2004/WD-xquery-20040723/#doc-xquery-ExprSingle)

The expression following the if keyword is called the test expression, and the expressions following the then and else keywords are called the then-expression and else-expression, respectively.

跟随在关键字if后的表达式称为测试表达式(test expression),跟随在关键字then 和 else后的表达式分别称为then表达式(then-expression)和sele表达式(else-expression)。

The first step in processing a conditional expression is to find the effective boolean value (http://www.w3.org/TR/2004/WD-xquery-20040723/#dt-ebv) of the test expression, as defined in 2.3.3 Effective Boolean Value.

处理一个条件表达式的第一步,是找到测试表达式的有效布尔值(effective boolean value),如2.3.3 Effective Boolean Value中所定义。

The value of a conditional expression is defined as follows: If the effective boolean value of the test expression is true, the value of the then-expression is returned. If the effective boolean value of the test expression is false, the value of the else-expression is returned.

一个条件表达式的值定义如下:如果测试表达式的有效布尔值为true,则返回then表达式的值。如果测试表达式的有效布尔值为false,则返回else表达式的值。

Conditional expressions have a special rule for propagating dynamic errors (http://www.w3.org/TR/2004/WD-xquery-20040723/#dt-dynamic-error). If the effective value of the test expression is true, the conditional expression ignores (does not raise) any dynamic errors encountered in the else-expression. In this case, since the else-expression can have no observable effect, it need not be evaluated. Similarly, if the effective value of the test expression is false, the conditional expression ignores any dynamic errors (http://www.w3.org/TR/2004/WD-xquery-20040723/#dt-dynamic-error) encountered in the then-expression, and the then-expression need not be evaluated.

条件表达式有一个传播动态错误(dynamic errors)的特殊规则。如果测试表达式的有效值为true,条件表达式忽略(不是引发)任何else表达式中遇到的动态错误。在这种情况下,既然else表达式没有值得注意的作用,它不需要被求值。同样地,如果测试表达式的有效值为false,条件表达式忽略then表达式中遇到的任何动态错误(dynamic errors),而且then表达式不需要被求值。

Here are some examples of conditional expressions:

下面是一些条件表达式的例子:


In this example, the test expression is a comparison expression:

• 本例中,测试表达式是一个比较表达式:

if ($widget1/unit-cost < $widget2/unit-cost)

  then $widget1
else $widget2



In this example, the test expression tests for the existence of an attribute named discounted, independently of its value:

• 本例中,测试表达式测试属性名discounted的存在,不依赖与属性值:

if ($part/@discounted)

  then $part/wholesale 
else $part/retail


3.11 Quantified Expressions

Quantified expressions support existential and universal quantification. The value of a quantified expression is always true or false.



[37]    QuantifiedExpr (http://www.w3.org/TR/2004/WD-xquery-20040723/#prod-xquery-QuantifiedExpr)    ::=    (("some" "$") | ("every" "$")) VarName (http://www.w3.org/TR/2004/WD-xquery-20040723/#doc-xquery-VarName) TypeDeclaration (http://www.w3.org/TR/2004/WD-xquery-20040723/#doc-xquery-TypeDeclaration)? "in" ExprSingle (http://www.w3.org/TR/2004/WD-xquery-20040723/#doc-xquery-ExprSingle) ("," "$" VarName (http://www.w3.org/TR/2004/WD-xquery-20040723/#doc-xquery-VarName) TypeDeclaration (http://www.w3.org/TR/2004/WD-xquery-20040723/#doc-xquery-TypeDeclaration)? "in" ExprSingle (http://www.w3.org/TR/2004/WD-xquery-20040723/#doc-xquery-ExprSingle))* "satisfies" ExprSingle (http://www.w3.org/TR/2004/WD-xquery-20040723/#doc-xquery-ExprSingle)

A quantified expression begins with a quantifier, which is the keyword some or every, followed by one or more in-clauses that are used to bind variables, followed by the keyword satisfies and a test expression. Each in-clause associates a variable with an expression that returns a sequence of values. The in-clauses generate tuples of variable bindings, using values drawn from the Cartesian product of the sequences returned by the binding expressions. Conceptually, the test expression is evaluated for each tuple of variable bindings. Results depend on the effective boolean values of the test expressions, as defined in 2.3.3 Effective Boolean Value. The value of the quantified expression is defined by the following rules:


If the quantifier is some, the quantified expression is true if at least one evaluation of the test expression has the effective boolean value true; otherwise the quantified expression is false. This rule implies that, if the in-clauses generate zero binding tuples, the value of the quantified expression is false.


If the quantifier is every, the quantified expression is true if every evaluation of the test expression has the effective boolean value true; otherwise the quantified expression is false. This rule implies that, if the in-clauses generate zero binding tuples, the value of the quantified expression is true.
The scope of a variable bound in a quantified expression comprises all subexpressions of the quantified expression that appear after the variable binding. The scope does not include the expression to which the variable is bound.
Each variable bound in an in-clause of a quantified expression may have an optional type declaration, which is a datatype declared using the syntax in 2.4.4 SequenceType Matching. If the type of a value bound to the variable does not match the declared type according to the rules for SequenceType matching (http://www.w3.org/TR/2004/WD-xquery-20040723/#dt-sequencetype-matching), a type error (http://www.w3.org/TR/2004/WD-xquery-20040723/#dt-type-error) is raised.[err:XP0004 (http://www.w3.org/TR/2004/WD-xquery-20040723/#ERRXP0004)][err:XP0006 (http://www.w3.org/TR/2004/WD-xquery-20040723/#ERRXP0006)]
The order in which test expressions are evaluated for the various binding tuples is implementation-dependent (http://www.w3.org/TR/2004/WD-xquery-20040723/#dt-implementation-dependent). If the quantifier is some, an implementation may return true as soon as it finds one binding tuple for which the test expression has an effective boolean value of true, and it may raise a dynamic error (http://www.w3.org/TR/2004/WD-xquery-20040723/#dt-dynamic-error) as soon as it finds one binding tuple for which the test expression raises an error. Similarly, if the quantifier is every, an implementation may return false as soon as it finds one binding tuple for which the test expression has an effective boolean value of false, and it may raise a dynamic error (http://www.w3.org/TR/2004/WD-xquery-20040723/#dt-dynamic-error) as soon as it finds one binding tuple for which the test expression raises an error. As a result of these rules, the value of a quantified expression is not deterministic in the presence of errors, as illustrated in the examples below.
Here are some examples of quantified expressions:


This expression is true if every part element has a discounted attribute (regardless of the values of these attributes):


every $part in //part satisfies $part/@discounted



This expression is true if at least one employee element satisfies the given comparison expression:


some $emp in //employee satisfies ($emp/bonus > 0.25 * $emp/salary)



In the following examples, each quantified expression evaluates its test expression over nine tuples of variable bindings, formed from the Cartesian product of the sequences (1, 2, 3) and (2, 3, 4). The expression beginning with some evaluates to true, and the expression beginning with every evaluates to false.


some $x in (1, 2, 3), $y in (2, 3, 4)

     satisfies $x + $y = 4



every $x in (1, 2, 3), $y in (2, 3, 4)

     satisfies $x + $y = 4



This quantified expression may either return true or raise a type error (http://www.w3.org/TR/2004/WD-xquery-20040723/#dt-type-error), since its test expression returns true for one variable binding and raises a type error (http://www.w3.org/TR/2004/WD-xquery-20040723/#dt-type-error) for another:


some $x in (1, 2, "cat") satisfies $x * 2 = 4



This quantified expression may either return false or raise a type error (http://www.w3.org/TR/2004/WD-xquery-20040723/#dt-type-error), since its test expression returns false for one variable binding and raises a type error (http://www.w3.org/TR/2004/WD-xquery-20040723/#dt-type-error) for another:


every $x in (1, 2, "cat") satisfies $x * 2 = 4



This quantified expression contains a type declaration that is not satisfied by every item in the test expression. If the Static Typing Feature (http://www.w3.org/TR/2004/WD-xquery-20040723/#dt-static-typing-feature) is implemented, this expression raises a type error (http://www.w3.org/TR/2004/WD-xquery-20040723/#dt-type-error) during the analysis phase. Otherwise, the expression may either return true or raise a type error (http://www.w3.org/TR/2004/WD-xquery-20040723/#dt-type-error) during the evaluation phase.


some $x as xs:integer in (1, 2, "cat") satisfies $x * 2 = 4


3.12 Expressions on SequenceTypes

In addition to their use in function parameters and results, SequenceTypes (http://www.w3.org/TR/2004/WD-xquery-20040723/#dt-sequence-type) are used in instance of, typeswitch, cast, castable, and treat expressions.

3.12.1 Instance Of



[49]    InstanceofExpr (http://www.w3.org/TR/2004/WD-xquery-20040723/#prod-xquery-InstanceofExpr)    ::=    TreatExpr (http://www.w3.org/TR/2004/WD-xquery-20040723/#doc-xquery-TreatExpr) ( "instance" "of" SequenceType (http://www.w3.org/TR/2004/WD-xquery-20040723/#doc-xquery-SequenceType) )?

The boolean operator instance of returns true if the value of its first operand matches the SequenceType in its second operand, according to the rules for SequenceType matching (http://www.w3.org/TR/2004/WD-xquery-20040723/#dt-sequencetype-matching); otherwise it returns false. For example:


5 instance of xs:integer
This example returns true because the given value is an instance of the given type.


5 instance of xs:decimal
This example returns true because the given value is an integer literal, and xs:integer is derived by restriction from xs:decimal.


<a>{5}</a> instance of xs:integer
This example returns false because the given value is not an integer; instead, it is an element containing an integer.


. instance of element()
This example returns true if the context item is an element node. If the context item is undefined, a dynamic error is raised.[err:XP0002 (http://www.w3.org/TR/2004/WD-xquery-20040723/#ERRXP0002)]

3.12.2 Typeswitch




[38]    TypeswitchExpr (http://www.w3.org/TR/2004/WD-xquery-20040723/#prod-xquery-TypeswitchExpr)    ::=    "typeswitch" "(" Expr (http://www.w3.org/TR/2004/WD-xquery-20040723/#doc-xquery-Expr) ")" CaseClause (http://www.w3.org/TR/2004/WD-xquery-20040723/#doc-xquery-CaseClause)+ "default" ("$" VarName (http://www.w3.org/TR/2004/WD-xquery-20040723/#doc-xquery-VarName))? "return" ExprSingle (http://www.w3.org/TR/2004/WD-xquery-20040723/#doc-xquery-ExprSingle)
[39]    CaseClause (http://www.w3.org/TR/2004/WD-xquery-20040723/#prod-xquery-CaseClause)    ::=    "case" ("$" VarName (http://www.w3.org/TR/2004/WD-xquery-20040723/#doc-xquery-VarName) "as")? SequenceType (http://www.w3.org/TR/2004/WD-xquery-20040723/#doc-xquery-SequenceType) "return" ExprSingle (http://www.w3.org/TR/2004/WD-xquery-20040723/#doc-xquery-ExprSingle)

The typeswitch expression chooses one of several expressions to evaluate based on the dynamic type of an input value.
In a typeswitch expression, the typeswitch keyword is followed by an expression enclosed in parentheses, called the operand expression. This is the expression whose type is being tested. The remainder of the typeswitch expression consists of one or more case clauses and a default clause.
Each case clause specifies a SequenceType (http://www.w3.org/TR/2004/WD-xquery-20040723/#dt-sequence-type) followed by a return expression. The effective case is the first case clause such that the value of the operand expression matches the SequenceType in the case clause, using the rules of SequenceType matching (http://www.w3.org/TR/2004/WD-xquery-20040723/#dt-sequencetype-matching). The value of the typeswitch expression is the value of the return expression in the effective case. If the value of the operand expression is not a value of any type named in a case clause, the value of the typeswitch expression is the value of the return expression in the default clause.
A case or default clause may optionally specify a variable name. Within the return expression of the case or default clause, this variable name is bound to the value of the operand expression, and its static type (http://www.w3.org/TR/2004/WD-xquery-20040723/#dt-static-type) is considered to be the SequenceType named in the case or default clause. If the return expression does not depend on the value of the operand expression, the variable may be omitted from the case or default clause.
The scope of a variable binding in a case or default clause comprises that clause. It is not an error for more than one case or default clause in the same typeswitch expression to bind variables with the same name.
The following example shows how a typeswitch expression might be used to process an expression in a way that depends on its dynamic type.


typeswitch($customer/billing-address)

   case $a as element(*, USAddress) return $a/state
case $a as element(*, CanadaAddress) return $a/province
case $a as element(*, JapanAddress) return $a/prefecture
default return "unknown"


3.12.3 Cast




[52]    CastExpr (http://www.w3.org/TR/2004/WD-xquery-20040723/#prod-xquery-CastExpr)    ::=    UnaryExpr (http://www.w3.org/TR/2004/WD-xquery-20040723/#doc-xquery-UnaryExpr) ( "cast" "as" SingleType (http://www.w3.org/TR/2004/WD-xquery-20040723/#doc-xquery-SingleType) )?
[108]    SingleType (http://www.w3.org/TR/2004/WD-xquery-20040723/#prod-xquery-SingleType)    ::=    AtomicType (http://www.w3.org/TR/2004/WD-xquery-20040723/#doc-xquery-AtomicType) "?"?

Occasionally it is necessary to convert a value to a specific datatype. For this purpose, XQuery provides a cast expression that creates a new value of a specific type based on an existing value. A cast expression takes two operands: an input expression and a target type. The type of the input expression is called the input type. The target type must be a named atomic type, represented by a QName, optionally followed by the occurrence indicator ? if an empty sequence is permitted. If the target type has no namespace prefix, it is considered to be in the default element/type namespace (http://www.w3.org/TR/2004/WD-xquery-20040723/#dt-def-elemtype-ns). The semantics of the cast expression are as follows:


Atomization (http://www.w3.org/TR/2004/WD-xquery-20040723/#dt-atomization) is performed on the input expression.


If the result of atomization is a sequence of more than one atomic value, a type error (http://www.w3.org/TR/2004/WD-xquery-20040723/#dt-type-error) is raised.[err:XP0004 (http://www.w3.org/TR/2004/WD-xquery-20040723/#ERRXP0004)][err:XP0006 (http://www.w3.org/TR/2004/WD-xquery-20040723/#ERRXP0006)]


If the result of atomization is an empty sequence:


If ? is specified after the target type, the result of the cast expression is an empty sequence.


If ? is not specified after the target type, a type error (http://www.w3.org/TR/2004/WD-xquery-20040723/#dt-type-error) is raised.[err:XP0004 (http://www.w3.org/TR/2004/WD-xquery-20040723/#ERRXP0004)][err:XP0006 (http://www.w3.org/TR/2004/WD-xquery-20040723/#ERRXP0006)]


If the result of atomization is a single atomic value, the result of the cast expression depends on the input type and the target type. In general, the cast expression attempts to create a new value of the target type based on the input value. Only certain combinations of input type and target type are supported. A summary of the rules are listed below— the normative definition of these rules is given in [XQuery 1.0 and XPath 2.0 Functions and Operators (http://www.w3.org/TR/2004/WD-xquery-20040723/#FunctionsAndOperators)]. For the purpose of these rules, an implementation may determine that one type is derived by restriction from another type either by examining the in-scope schema definitions (http://www.w3.org/TR/2004/WD-xquery-20040723/#dt-issd) or by using an alternative, implementation-dependent (http://www.w3.org/TR/2004/WD-xquery-20040723/#dt-implementation-dependent) mechanism such as a data dictionary.


cast is supported for the combinations of input type and target type listed in [XQuery 1.0 and XPath 2.0 Functions and Operators (http://www.w3.org/TR/2004/WD-xquery-20040723/#FunctionsAndOperators)]. For each of these combinations, both the input type and the target type are primitive schema types. For example, a value of type xs:string can be cast into the type xs:decimal. For each of these built-in combinations, the semantics of casting are specified in [XQuery 1.0 and XPath 2.0 Functions and Operators (http://www.w3.org/TR/2004/WD-xquery-20040723/#FunctionsAndOperators)].


cast is supported if the input type is a non-primitive atomic type that is derived by restriction from the target type. In this case, the input value is mapped into the value space of the target type, unchanged except for its type. For example, if shoesize is derived by restriction from xs:integer, a value of type shoesize can be cast into the type xs:integer.


cast is supported if the target type is a non-primitive atomic type and the input type is xs:string or xdt:untypedAtomic. The input value is first converted to a value in the lexical space of the target type by applying the whitespace normalization rules for the target type; a dynamic error (http://www.w3.org/TR/2004/WD-xquery-20040723/#dt-dynamic-error) [err:XP0029 (http://www.w3.org/TR/2004/WD-xquery-20040723/#ERRXP0029)] is raised if the resulting lexical value does not satisfy the pattern facet of the target type. The lexical value is then converted to the value space of the target type using the schema-defined rules for the target type; a dynamic error (http://www.w3.org/TR/2004/WD-xquery-20040723/#dt-dynamic-error)[err:XP0029 (http://www.w3.org/TR/2004/WD-xquery-20040723/#ERRXP0029)] is raised if the resulting value does not satisfy all the facets of the target type.


cast is supported if the target type is a non-primitive atomic type that is derived by restriction from the input type. The input value must satisfy all the facets of the target type (in the case of the pattern facet, this is checked by generating a string representation of the input value, using the rules for casting to xs:string). The resulting value is the same as the input value, but with a different dynamic type.


If a primitive type P1 can be cast into a primitive type P2, then any type derived by restriction from P1 can be cast into any type derived by restriction from P2, provided that the facets of the target type are satisfied. First the input value is cast to P1 using rule (b) above. Next, the value of type P1 is cast to the type P2, using rule (a) above. Finally, the value of type P2 is cast to the target type, using rule (d) above.


For any combination of input type and target type that is not in the above list, a cast expression raises a type error (http://www.w3.org/TR/2004/WD-xquery-20040723/#dt-type-error).[err:XP0004 (http://www.w3.org/TR/2004/WD-xquery-20040723/#ERRXP0004)][err:XP0006 (http://www.w3.org/TR/2004/WD-xquery-20040723/#ERRXP0006)]
If casting from the input type to the target type is supported but nevertheless it is not possible to cast the input value into the value space of the target type, a dynamic error (http://www.w3.org/TR/2004/WD-xquery-20040723/#dt-dynamic-error) is raised.[err:XP0021 (http://www.w3.org/TR/2004/WD-xquery-20040723/#ERRXP0021)] This includes the case when any facet of the target type is not satisfied. For example, the expression "2003-02-31" cast as xs:date would raise a dynamic error (http://www.w3.org/TR/2004/WD-xquery-20040723/#dt-dynamic-error).

3.12.4 Castable



[51]    CastableExpr (http://www.w3.org/TR/2004/WD-xquery-20040723/#prod-xquery-CastableExpr)    ::=    CastExpr (http://www.w3.org/TR/2004/WD-xquery-20040723/#doc-xquery-CastExpr) ( "castable" "as" SingleType (http://www.w3.org/TR/2004/WD-xquery-20040723/#doc-xquery-SingleType) )?

XQuery provides an expression that tests whether a given value is castable into a given target type. The expression V castable as T returns true if the value V can be successfully cast into the target type T by using a cast expression; otherwise it returns false. The castable predicate can be used to avoid errors at evaluation time. It can also be used to select an appropriate type for processing of a given value, as illustrated in the following example:


if ($x castable as hatsize)

   then $x cast as hatsize 
else if ($x castable as IQ)
then $x cast as IQ
else $x cast as xs:string


3.12.5 Constructor Functions

For every atomic type in the in-scope type definitions (http://www.w3.org/TR/2004/WD-xquery-20040723/#dt-is-types) that is in a namespace, a constructor function is provided. In each case, the name of the constructor function is the same as the name of its target type (including namespace). The signature of the constructor function for type T is as follows:


T($arg as xdt:anyAtomicType?) as T?


Constructor functions are normatively defined in [XQuery 1.0 and XPath 2.0 Functions and Operators (http://www.w3.org/TR/2004/WD-xquery-20040723/#FunctionsAndOperators)]. In general, if the argument to a constructor function is of type xs:string, the string is whitespace-normalized and converted to the target type by schema validation; otherwise, the semantics of the constructor function are identical to $arg cast as T.
The following examples illustrate the use of constructor functions:


This example is equivalent to "2000-01-01" cast as xs:date.


xs:date("2000-01-01")



This example is equivalent to ($floatvalue * 0.2E-5) cast as xs:decimal.


xs:decimal($floatvalue * 0.2E-5)



This example returns a xdt:dayTimeDuration value equal to 21 days. It is equivalent to "P21D" cast as xdt:dayTimeDuration.


xdt:dayTimeDuration("P21D")



If usa:zipcode is a user-defined atomic type in the in-scope type definitions (http://www.w3.org/TR/2004/WD-xquery-20040723/#dt-is-types), then the following expression is equivalent to the expression "12345" cast as usa:zipcode.


usa:zipcode("12345")


Atomic types that are not in a namespace do not have constructor functions. To construct an instance of such a type, it is necessary to use a cast expression. For example, if the user-defined type apple is derived from xs:integer but is not in a namespace, an instance of this type can be constructed as follows (but only if the default element/type namespace (http://www.w3.org/TR/2004/WD-xquery-20040723/#dt-def-elemtype-ns) is no namespace):


17 cast as apple


3.12.6 Treat



[50]    TreatExpr (http://www.w3.org/TR/2004/WD-xquery-20040723/#prod-xquery-TreatExpr)    ::=    CastableExpr (http://www.w3.org/TR/2004/WD-xquery-20040723/#doc-xquery-CastableExpr) ( "treat" "as" SequenceType (http://www.w3.org/TR/2004/WD-xquery-20040723/#doc-xquery-SequenceType) )?

XQuery provides an expression called treat that can be used to modify the static type (http://www.w3.org/TR/2004/WD-xquery-20040723/#dt-static-type) of its operand.
Like cast, the treat expression takes two operands: an expression and a SequenceType (http://www.w3.org/TR/2004/WD-xquery-20040723/#dt-sequence-type). Unlike cast, however, treat does not change the dynamic type or value of its operand. Instead, the purpose of treat is to ensure that an expression has an expected type at evaluation time.
The semantics of expr1 treat as type1 are as follows:


During static analysis:
The static type (http://www.w3.org/TR/2004/WD-xquery-20040723/#dt-static-type) of the treat expression is type1. This enables the expression to be used as an argument of a function that requires a parameter of type1.


During expression evaluation:
If expr1 matches type1, using the rules for SequenceType matching (http://www.w3.org/TR/2004/WD-xquery-20040723/#dt-sequencetype-matching), the treat expression returns the value of expr1; otherwise, it raises a dynamic error (http://www.w3.org/TR/2004/WD-xquery-20040723/#dt-dynamic-error).[err:XP0050 (http://www.w3.org/TR/2004/WD-xquery-20040723/#ERRXP0050)] If the value of expr1 is returned, its identity is preserved. The treat expression ensures that the value of its expression operand conforms to the expected type at run-time.


Example:


$myaddress treat as element(*, USAddress)


The static type (http://www.w3.org/TR/2004/WD-xquery-20040723/#dt-static-type) of $myaddress may be element(*, Address), a less specific type than element(*, USAddress). However, at run-time, the value of $myaddress must match the type element(*, USAddress) using rules for SequenceType matching (http://www.w3.org/TR/2004/WD-xquery-20040723/#dt-sequencetype-matching); otherwise a dynamic error (http://www.w3.org/TR/2004/WD-xquery-20040723/#dt-dynamic-error) is raised.[err:XP0050 (http://www.w3.org/TR/2004/WD-xquery-20040723/#ERRXP0050)]

3.13 Validate Expressions



[58]