跳转到内容

XQuery/陷阱

来自维基教科书,开放的书籍,开放的世界

广义等于

[编辑 | 编辑源代码]

= 是一个序列比较运算符,如果交集不为空,则为真。因此

(1, 2, 3) = (3, 4, 5)

 3 = (3, 4, 5)

但有一些怪异之处。例如

 () = ()

为假,同样

 () != ()

运算符 eq 用于比较值。

算术运算符

[编辑 | 编辑源代码]

减号需要在其周围留出空格,因为 $x-3 是一个有效的变量名,它与 $x - 3 不同。

匹配括号等

[编辑 | 编辑源代码]

仔细检查匹配的单引号和双引号,圆括号和方括号以及花括号。Java 客户端会显示匹配的括号,但错误通常由 XQuery 编译器诊断不佳。


:= is the binding operator.

多个绑定语句可以用逗号分隔的简写形式

 let $x := 3
 let $y := 4
 let $x := "fred"
          

简化为

 let $x := 3,
     $y := 4,
     $x := "fred"


很方便,但在修改代码时会导致错误。考虑避免这种语法。

条件表达式

[编辑 | 编辑源代码]

条件表达式必须有 else 部分。如果不需要其中一个备选方案,则返回空序列 ()

if ($x = 4) 
then "Four"
else ()

'Order by' 将数字按文本排序

  order by $c/population

要按数字进行排序,必须使用 number() 函数

  order by number($C/population)

或强制转换为数字类型

  order by xs:integer($c/population)   

  order by $c/population cast as xs:integer

XML 构造

[编辑 | 编辑源代码]

只需开始一个标签,就可以构建 XML。这些标签实际上是 XQuery 表达式运算符。但是,这会将您置于一个词法范围,其中所有内容都是 XML,而花括号则切换回正常的 XQuery(而一个打开的标签将切换回 XML)。用双花括号 ({{ }}) 转义花括号。

注意 XQuery 和 XML 构造模式之间的切换

 let $a:= "bob"
 let $b:= "jane"
 let $ab := ($a, $b)
 return 
   <people>
   { for $person in $ab
     return <person> {$person} </person>
   }
   </people>

XQuery 中的注释使用 (: ... :),而 XML 中的注释使用 <!-- ... -->

在错误的上下文中很容易使用错误的类型,特别是构造的 XML 中的 XQuery 注释。

<A> (: a comment :) </A>

使注释成为 XML 元素的文本部分。

let 语句是 FLWOR 表达式的一部分,不能单独出现。XQuery 是一种函数式语言,let 语句只是对名称到表达式的临时绑定。

let $x := 5
return $x

函数结果

[编辑 | 编辑源代码]

函数中不需要 return。它是 FLWOR 语句的一部分,本身不是语句(如 let)。因此,如果没有任何 forlet,则不需要它,也不允许它。

 declare function local:sum($a, $b) {
   $a + $b
 }

declare function local:sum($a, $b) {
   let $c := $a + $b
   return $c
 }
 

但不是

 declare function local:sum($a, $b) {
   return $a + $b
 }

双精度浮点数和浮点数的舍入

[编辑 | 编辑源代码]

您可能会对以下结果感到惊讶

number(3.1) + number(3.2)

是 6.30000000000001 这是因为 number() 将值强制转换为双精度浮点数,双精度浮点数使用统计上接近的算法对值进行舍入,该算法在使用许多数字时会失败,但在这种特定的测试用例中会失败。从技术上讲,这不是错误,其他系统(Scala、ruby、python 等)也会生成相同的错误。解决此问题的方法是不使用 number() 函数,而是强制转换为 xs:decimal()。

xs:decimal(3.1) + xs:decimal(3.2)
华夏公益教科书