跳轉到內容

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)
華夏公益教科書