XML - 管理資料交換/XQuery
| 上一章 | 下一章 |
| ← XQL | Exchanger XML Lite → |
XQuery 是一種由全球資訊網聯盟 (W3C) 開發的查詢語言,它使人們能夠高效便捷地從原生 XML 資料庫和儲存 XML 資料的關係資料庫中提取資訊。
每個查詢都包含一個引言和一個主體。引言建立了編譯時環境,例如模式和模組匯入、名稱空間和函式宣告以及使用者定義的函式。主體生成整個查詢的值。XQuery 的結構如圖 1 所示。
|
圖 1. XQuery 的結構 |
||
|
引言 |
註釋 |
(: 示例版本 1.0 :) |
|
名稱空間宣告 |
declare namespace my = “urn:foo”; |
|
|
函式宣告 |
declare function my:fact($n) { |
|
|
|
if ($n < 2) |
|
|
|
then 1 |
|
|
|
else $n * my:fact($n – 1) |
|
|
|
}; |
|
|
全域性變數 |
declare variable $my:ten {my:fact(10)}; |
|
|
|
||
|
主體 |
構造的 XML |
<table>{ |
|
FLWOR 表示式 |
for $i in 1 to 10 |
|
|
return |
||
|
|
<tr> |
|
|
封閉表示式 |
<td>10!/{$i}! = {$my:ten div my:fact($i)} </td> |
|
|
|
</tr> |
|
|
|
} </table> |
|
2.1 XQuery 與 XPath 和 XSLT 的比較
XQuery、XPath、XSLT 和 SQL 都是優秀的查詢語言。每種語言在不同的情況下都有其優勢,因此 XQuery 無法替代所有任務中的它們。XQuery 建立在 XPath 表示式的基礎上。XQuery 1.0 和 XPath 2.0 共享相同的資料模型、相同的函式和相同的語法。表 1 顯示了每種查詢語言的優缺點。
表 1. XQuery 與 XPath 和 XSLT 的比較
|
|
優勢 |
缺點 |
|
XQuery |
1. 表達連線和排序 2. 以任意順序操作值和節點的序列 3. 易於編寫使用者定義的函式,包括遞迴函式 4. 允許使用者在查詢中間構造臨時 XML 結果,然後導航到該結果 |
1. XQuery 實現不如 XSLT 實現成熟 |
|
XPath 1.0 |
1. 用於定址 XML 文件部分的便捷語法 2. 從現有 XML 文件或資料庫中選擇節點 |
1. 無法建立新的 XML 2. 無法僅選擇 XML 節點的一部分 3. 無法引入變數或名稱空間繫結 4. 無法處理日期值,計算數字集的最大值或對字串列表進行排序 |
|
XSLT 1.0 |
1. 遞迴處理 XML 文件或將 XML 翻譯成 HTML 和文字 2. 建立新的 XML 或現有節點的一部分 3. 引入變數和名稱空間 |
1. 無法在不建立類似於 XQuery 的語言的情況下進行定址 2. 無法處理值序列 |
2.2 XQuery 與 SQL 的比較
XQuery 在風格和語法上與 SQL 有相似之處。XQuery 和 SQL 之間的主要區別在於,SQL 專注於“扁平”行的無序集,而 XQuery 專注於值的序列和層次節點的有序序列。
3.1 FLWOR 表示式
FLWOR 表示式是 XQuery 的重要組成部分。FLWOR 的發音為“flower”。這個名字來自FOR、LET、WHERE、ORDER BY 和RETURN 子句,這些子句組織了表示式。FOR 和 LET 子句可以在任何順序出現任意次數。WHERE 和 ORDER BY 子句是可選的。但是,如果使用這些子句,則必須按給定的順序顯示它們。RETURN 子句必須存在。
XQuery 允許您以類似於 SQL 的方式使用連線查詢。此示例在示例 1 中被描繪為影片表和演員表之間的連線。
示例 1.
let $doc := .
for $v in $doc//video,
$a in $doc//actors/actor
where ends-with($a, 'Lisa')
and $v/actorRef = $a/@id
order by $v/year
return $v/title
LET 子句表示變數賦值。在本例中,查詢將其初始化為 doc ('videos.xml'),或查詢的結果將文件放置在資料庫中。FOR 子句描述了一種迭代機制:一個變數依次處理所有影片,另一個變數依次處理所有演員。在本例中,查詢處理影片和演員的配對。WHERE 子句選擇您感興趣的表。在本例中,您想知道演員是否出現在影片表中,且姓名以“Lisa”結尾。ORDER BY 子句以排序順序獲取結果。在本例中,您希望結果按影片的釋出日期排序。表示式末尾的RETURN 子句通知系統您想要獲取哪些資訊。在本例中,您想要影片的標題。
3.2 條件表示式
XQuery 提供了 IF、THEN 和 ELSE 子句,即條件表示式。ELSE 子句是強制性的。原因是 XQuery 中的每個表示式都應該返回一個值。示例 2 中顯示了一個查詢,以檢索所有書籍及其作者。您希望在頭兩個作者之後將其他作者作為“et-al”返回。
示例 2.
for $b in document("books.xml")/bib/book
return
if (count($b/author) <= 2) then $b
else <book> { $b/@*, $b/title, $b/author[position() <= 2], <et-al/>,
...... $b/publisher, $b/price } </book>
此查詢從 books.xml 中讀取書籍資料。如果每本書的作者數量小於 2 或等於 2,則查詢直接返回書籍。否則,查詢建立一個包含所有原始資料的新的書籍元素,但查詢只包含頭兩個作者,並將 et-al 元素附加到其中。position() 函式只返回頭兩個作者。$b/@*,XPath 表示式,指的是 $b 上的所有屬性。
3.3 XQuery 函式和運算子
XQuery 包含大量函式和運算子。表 2 顯示了常用的內建函式。您可以描述自己的函式,並且許多引擎也提供自定義擴充套件。
表 2. 常用的內建函式
|
函式 |
說明 |
|
數學 +, -, *, div, idiv, mod, =, !=, <, >, <=, >= floor(), ceiling(), round(), count(), min(), max(), avg(), sum() |
除法使用 div 而不是斜槓進行,因為斜槓表示 XPath 步進表示式。 idiv 是一個專門用於整數除法的運算子,它返回一個整數並忽略任何餘數。 |
|
字串和正則表示式 compare(), concat(), starts-with(), ends-with(), contains(), substring(), string-length(), substring-before(), substring-after(), normalize-space(), upper-case(), lower-case(), translate(), matches(), replace(), tokenize() |
compare() 指示字串排序。 translate() 執行字元的特殊對映。 matches()、replace() 和 tokenize() 使用正則表示式查詢、操作和拆分字串值。 |
|
日期和時間 current-date(), current-time(), current-dateTime() +, -, div eq, ne, lt, gt, le, gt |
XQuery 具有許多用於日期和時間值的特殊型別,例如 duration、dateTime、date 和 time。在大多數情況下,您可以像處理數字一樣對其進行算術運算和比較運算。兩個字母的縮寫代表等於、不等於、小於、大於、小於或等於以及大於或等於。 |
|
XML 節點和 QNames node-kind(),node-name(),base-uri() eq,ne,is,isnot,get-local-name-from-QName(),get-namespace-from-QName() deep-equal() >>,<< |
node-kind() 返回節點的型別(例如“元素”)。node-name() 返回節點的 QName,如果存在的話。base-uri() 返回此節點所在的 URI。 節點和 QName 值也可以使用 eq 和 ne(用於值比較)進行比較,或者使用 is 和 isnot(用於身份比較)。deep-equal() 根據兩個節點的完整遞迴內容進行比較。 << 運算子在左運算元在文件順序中preceeds右運算元時返回 true。>> 運算子是後續比較。 |
|
序列 item-at(),index-of(),empty(),exists(),distinct-nodes(),distinct-values(),insert(),remove(),subsequence(),unordered()。position(),last() |
item-at() 返回給定位置的項,而 index-of() 嘗試為給定項查詢位置。 empty() 在序列為空時返回 true,exists() 在序列不為空時返回 true。 dictinct-nodes() 返回一個序列,其中完全相同的節點被移除,而 distinct-values() 返回一個序列,其中任何重複的原子值被移除。 unordered() 允許查詢引擎在不保留順序的情況下進行最佳化。 position() 返回當前正在處理的上下文項的位置。 last() 返回最後一項的索引。 |
|
型別轉換 string(),data(),decimal(),boolean() |
這些函式在可能的情況下返回給定型別的節點。 data() 返回節點的“型別化值”。 |
|
布林值 true(),false(),not() |
在 XQuery 中沒有“true”或“false”關鍵字,而是使用 true() 和 false() 函式。 not() 返回其引數的 boolean 取反。 |
|
輸入 document(),input(),collection() |
document() 根據 URI 引數返回節點的文件。 collection() 根據字串引數(可能是多個文件)返回集合。 input() 返回引擎提供的通用輸入節點集。 |
4. 參考資料
[edit | edit source]本章內容摘自以下列表。
- X Is for XQuery, Jason Hunter: http://www.oracle.com/technology/oramag/oracle/03-may/o33devxml.html
- An Introduction to the XQuery FLWOR Expression, Michael Kay: http://www.stylusstudio.com/xquery_flwor.html
- Learn XQuery in 10 Minutes, Michael Kay: http://www.stylusstudio.com/xquery_primer.html
- XQuery: The XML Query Language, Michael Brundage, Addison-Wesley 2004
5. 有用連結和書籍
[edit | edit source]- W3C XML Query (XQuery): http://www.w3.org/XML/Query
- XQuery 最新版本:http://www.w3.org/TR/xquery/
- XQuery 1.0 和 XPath 2.0 函式和運算子:http://www.w3.org/TR/xpath-functions/
- XQuery 1.0 和 XPath 2.0 資料模型 (XDM):http://www.w3.org/TR/xpath-datamodel/
- XSLT 2.0 和 XQuery 1.0 序列化:http://www.w3.org/TR/xslt-xquery-serialization/
- XML Query 用例:http://www.w3.org/TR/xquery-use-cases/
- XML Query (XQuery) 需求:http://www.w3.org/TR/xquery-requirements/
- XQuery: The XML Query Language, Michael Brundage, Addison-Wesley 2004
另請參閱
[edit | edit source]- XQuery 教程和食譜華夏公益教科書 這本華夏公益教科書包含許多 XQuery 小示例,並連結到可用的 XQuery 應用程式。