2003年8月對本文的修改加入了 XQUery 規范的最新更改:增加了一個新的 XQuery Serialization 和兩個 全文相關的(Full-Text-related)規范,其他10個工作草案中有8個包含了新的內容,還有兩個處于最后請求(Last Call)狀態。實現者列表也有大幅度的增加。
W3C 的 XQuery 規范已經準備了很長時間。它啟動于 1998 年由 W3C 發起的查詢語言專題討論會。來自業界、學術界和研究團體的受邀代表利用這個機會發表了各自的看法,闡述了他們認為重要的 XML 查詢語言的特性和需求。
兩大不同的陣營
可以在線獲取這 66篇演講稿,它們主要來自兩大不同的陣營:那些將 XML 主要 作為文檔使用的人(這很大程度上反映了 XML 起源于 SGML)和將 XML 作為數據使用的人 -- 后者很大程度上反映了 XML 在中間件領域、前端傳統關系數據庫領域中不斷增長的現狀。
尤其是俄勒岡州研究生院的 David Maier的演講稿“Database Desiderata for an XML Query Language”,它非常簡明扼要,最初的時候有人多次向我提到過它,說它是特別有助于了解波士頓討論會之后成立的Query Language Working Group(查詢語言工作組)的文檔之一。
按照 W3C 的標準,這個工作組很龐大(據說只有Protocol Working Group(協議工作組)的成員比它多)。它由 30 多個成員公司構成,反映了這兩大陣營各自的觀點。現在合并而成的最終形式是一個 XML 查詢語言標準, 它很好地代表了這兩個團體的需求和觀點。
對于 XML 用戶來說,最熟悉的 XQuery 關鍵組件是 XPath,它本身就是一個 W3C 規范。單獨的 XPath 位置路徑本身 (“//book/editor” 意味著“在當前集合中查找所有圖書編輯”)就是完全有效的 XQuery。在數據方面,XQuery 具有類似于 SQL 的外觀和能力,這是來自關系數據庫世界的用戶所歡迎和熟悉的。
其卑微的出身
XQuery 是從 Quilt 開始的。最初作為用戶級語法的試驗器,Quilt 是基于整個工作組的協作成果的,用于定義需求、用例、底層數據模型和代數(參見下面)。Quilt 最初由 Jonathan Robie、Don Chamberlin 和 Daniela Florescu 開發。Robie 最出名的可能是他在 XQL 標準化和推廣方面所做的先驅工作,XQL 是 XQuery 的前身,也是目前 XML 查詢語言世界中最接近實際標準語言的一種語言,已經有十幾種實現在使用。Chamberlin 是 SQL 的共同設計者之一(這可是簡歷中值得稱道的一項!),也是“開發了大量當今關系數據庫技術”的 IBM 研究小組中的一員(摘自于他的 Web 站點)。Florescu 也不遜色。她的 Web 站點描述道,她在近 10 年之內,撰寫或與人合作撰寫了 50 多篇關于查詢語言優化和體系結構拓展的研究論文。
這三位作者提到了影響 Quilt 設計的幾種語言,包括 XQL、XML-QL 和 SQL。“XML Query Language: Experiences and Exemplars(XML查詢語言:經驗和實例)”是一篇非常有用的論文,對于前兩種語言以及叫做 YaTL 和 Lorel 的其他兩種語言進行了很好的比較性概述,該論文由 Mary Fernandez、Jerome Simeon 和 Phil Wadler 合著 -- 他們都是工作組成員。
考慮到數據和文檔團體的不同觀點以及所打下的堅實基礎(下面有詳細描述),為這個龐大的規范花費如此長的時間才向大眾公布也就不足為奇了。W3C 工作組的內部進展是嚴格保密的,并且在2001年2月中旬以前,查詢語言工作組的大多數工作都是秘密進行的。
很早就發布了 Requirements 文檔和 Data Model 工作草案,但是直到2001年2月,工作組的發布工作才得以進入高潮,那時大量的文檔開始推出。然后在2001年6月和12月、2002年8月和11月、和2003年5月進行了重要更新。在2003年5月加入了一個 XQuery 序列化和兩個全文相關的工作草案后,現在我們有了總共12個文檔(包括與 XSL 工作組共同分享的6個工作草案) ,它正在(我們希望!)接近成為完整的文檔集。
新生的發布王國
定義 XQuery 的、具有完全描述能力的文檔集現在包括:
- XML Query Requirements
- 工作組的規劃文檔。XQuery 需求列表。
- XML Query Use Cases
- 解決特定問題的幾個實際方案和 XQuery 代碼片段。
- XQuery 1.0: An XML Query Language
- 核心文檔,介紹語言本身,以及對大多數其他內容的概述。
- XQuery 1.0 and XPath 2.0 Data Model
- XML 信息集的擴展。描述查詢實現必須理解的數據項和形式語義的基礎。
- XQuery 1.0 and XPath 2.0 Formal Semantics
- 從形式上定義語言的底層代數。
- XML Syntax for XQuery 1.0 (XQueryX)
- 為喜歡使用 XML 的人提供的另一種語法。任何地方的機器都可以使用(至少現在是這樣,除非設計出更好的替代者)。
- XQuery 1.0 and XPath 2.0 Functions and Operators Version 1.0
- Schema 數據類型、 XQuery 節點和節點序列的基本函數和操作符。
- XML Path Language (XPath) 2.0
- 單獨分離出來的XPath 文檔。
- XPath Requirements Version 2.0
- XPath 的需求文檔。
- XSLT 2.0 and XQuery 1.0 Serialization
- 從 XQuery 1.0 和 XPath 2.0 Data Model 輸出的序列化“尖括號”XML。
- XML Query and XPath Full-Text Requirements
- 描述 Full-Text Recommendation 需要達到的功能需求。
- XML Query and XPath Full-Text Use Cases
- Full-Text 規范預期能夠處理的實際情況。
這些文檔代表了大量工作。XQuery 1.0: An XML Query Language 文檔是這個文檔集的關鍵,但是其他文檔也為 XQuery 成為良好的規范和全面支持的語言作出了貢獻。據我所知,這是出自 W3C 的最復雜的一套規范(雖然 XML Schema 或許可與之相比,但那又是另一回事了)。
如果您是第一次接觸如此大量的文檔,并且不知道從何處著手,我可以推薦兩種方法。可以從核心的 XQuery 1.0 文檔開始。它有一個很好的介紹性概述。另一種方法是從選擇一個 Use Cases 工作草案開始。那些文檔描述了可以應用 XQuery 的幾個實際方案。每個用例都以特定應用領域為目標,并針對該領域的示例數據列出了大量可能的 XQuery。如果希望看看實際工作語法的具體示例,這些代碼片段是十分有用的。
BabelFish,,您在哪兒?
XQuery 比 Certs 更出色:它實際上是整合了三種語言。首先是“表面(surface)”語法,它是三者之中最為人們所見的,也是用戶最有可能與之發生聯系的語法。其次,是另外一種基于 XML 的語法,它是一種計算機進程更易于處理的用于代替表面語言的語法。最后,還有一種形式代數語言,它十分詳細地描述了 XQuery 處理器的內部工作。
底層形式方法
Data Model and Formal Semantics(數據模型和形式語義)工作草案共同為 XQuery 提供了精確的、理論上的基礎支持。這兩個文檔詳細介紹了查詢 代數,這是用形式術語定義的一組精確定義,它定義了XQuery 查詢期望操作的核心實體、以及各種語言操作符怎樣使用那些操作數的公式。如果您不是查詢引擎的實現者、有較多的經費保障或者只是喜歡使用復雜的形式系統,那么您應該不會對它感興趣。
提供了一個讓實現者能夠將表面語法特性直接重新造型為底層代數的映射。正如一些廠商在 XML 商業展示會上所展示的那樣,可以實現實際上與代數直接溝通的查詢處理程序(雖然我認為這更多的是對概念的證明)。
這個代數還提供了詳細描述如何將復雜表達式優化及轉變成更簡單的等價形式的規則。我所能說的是(我不是語言學家,并且形式語義文檔讀起來并不輕松),它們都很好。特別是大型數據庫供應商會贊賞一種從頭開始設計并且經過優化而高效的查詢語言結構。
代數還提供了存放類型信息的位置。XQuery 是強類型的:如果數據有與其相關的 XML Schema,則處理程序可以根據該 Schema 進行驗證、并為查詢引擎提供文檔中節點數據類型的 后模式驗證信息集(Post-Schema-Validation-Infoset PSVI)信息,同時利用“XML Schema Part 2: Datatypes”中聲明的類型和自定義的用戶定義類型。代數還有靜態和動態類型檢查能力。例如,引擎可以使用 PSVI 派生的類型信息,以在編譯時靜態地檢查查詢表達式的數據類型(當分析查詢的語法正確性時)。在這個周期中盡早地確定類型無效的查詢,這樣能夠大大減少對大型數據集進行很可能是昂貴的(和無結果的)搜索的需要。XQuery 規范最新的工作包括了對與類型有關的語法的改變。
XPath 2.0 和剩余問題
XQuery 與 XPath 2.0 有同樣的公共數據模型,這一事實反映在數據模型文檔的有點尷尬的標題“XQuery 1.0 and XPath 2.0 Data Model”的標題上。XPath 2.0 幾乎已經成熟。數據模型描述了 XML 文檔中 XPath 處理程序感興趣的核心信息,并且 XPath 的步驟操作的最終語法和語義幾乎已經完成。全部規范屬于Query Language工作組和 XSL 工作組共同所有,并且這兩個工作組需要對 XPath 2.0 的未來達成一致。不論在政治上還是在技術上,這常常會帶來挑戰。不過,就算是達成一致的道路是崎嶇不平的,這兩個工作組看來并沒有表現出有多么不協調(至少在外人眼里如此)。
僅用一例說明為什么從 XPath 1.0 到 2.0 的轉換非常有意思,考慮這一情況:XPath 1.0 是基于集合的表達式語言。XPath 1.0 中的 4 種數據類型之一,節點集,也只不過就是:集合。根據定義,集合是無序的并且不包含重復成員。另一方面,XPath 2.0 是基于序列的。相比而言,XPath 2.0 中節點的序列(是否可類推稱它們為 節點序列?)是有序的,并且允許重復。用行話來說,這些差異的分歧存在于許多問題中,工作組需要各自和協作找出這些問題來,以便使他們都能夠與 XPath 2.0 協調一致。
什么時候才有可能解決剩余問題呢?我不知道。在 XQuery 1.0 工作草案附錄中列出了將近40個看來相當重要的問題并標記為“active”(如果它們是重要的,那么工作組現在應當已經解決它們了),但是當我一年前查看時,這個數字接近150,當時其他工作草案也有各自的附加問題列表。另一個表明過程進行的跡象,Data Model and Function and Operators 工作草案現在是處于 Last Call (最后請求)階段,這是成為 Candidate Recommendation(侯選推薦標準)的最后一個階段。所以隧道盡頭的光線確實是正在變亮。
XQueryX
XQueryX 是另一種基于 XML 的用于表面語言的語法的規范 ,它是較早加入到 XQuery 文檔家族的。XQuery 的需求之一是規定多個語法 應該是可能的 -- 聽起來像是工作組在避免下注 -- 如果是這樣,這些語法中的一個可能必須方便人們讀寫,另一個應該必須可用 XML 表示。
使用基于 XML 的查詢表達具有 XML 所有顯著的和已知的優點:它使標準工具易于解析、生成和詢問查詢內容。這可能很有用,例如,如果正在進行源碼級優化或轉換,那么它很可能取決于方便地檢查特定語法結構的查詢的能力。我們知道 XML 擅長這類任務。
盡管對于 XQueryX 做了這些早期工作,但是它是自 2001 年發布以后一次也沒有更新過的少數幾個工作草案之一。由于 Query 工作組沒有對 XQueryX 的將來做出任何正式的聲明, 所以看來顯然他們不會讓它以當前的形式進入 Recommendation(推薦標準) 狀態。當工作草案第一次發表時,對于其冗長的語法有大量疑問的聲音,難道這種批評使工作組覺得應該終止它?無論如何,目前 XQueryX 的未來尚不明確。
清單 1 顯示了使用 XQuery 語法的一個簡單查詢:
清單 1. 一個使用標準語法的簡單查詢
|
而清單 2顯示了使用 XQueryX 的等價查詢:
清單 2. 使用 XQueryX 格式的相同查詢:
|
對于處理它的計算機來說,這種冗長關系沒什么問題(除非我們談論的是 確實很大的查詢),但是對于人類操作員來說,要進行一些實際的調試就會有一些困難。
一個小警告:上述“/book/author”位置路徑的語法包含了我的一些猜測成分,附錄中的 DTD 和 schema 對于這種表達式類型的確切語法有一些不明確的地方。這是使用早期規范存在缺陷的實例。
準備就緒,然后該如何呢?
當我2001年6月第一次撰寫當時 XQuery 實現的概述時,XQuery 的第一個主要版本剛剛發表,當時只有兩個實現:我自己的和 Microsoft 的。這使我有機會在文章中打趣說 Bill 和我正在爭奪市場。這一次,經過兩年時間和后來發布的五個工作草案,開這種玩笑的時機早已遠去。已經有了20多種實現和一些相關的產品和工具。
了解當前發展情況的最好地點是 XML Query 的主頁。這里的列表都是非常活躍的,我預計隨著人們的興趣和推動力量的增加以及規范越來越接近于 Recommendation(推薦標準)狀態,我們將會看到新的實現不斷涌現。
語法:快速樣板
讓我們用一個實際的例子快速看一下 XQuery 的幾項功能。下面是一個簡單的查詢,它操作 Use Cases 文檔中的規范示例文件。該查詢展示了 XQuery 投影(在數據集中選擇與所定標準匹配的節點子集)和 轉換(生成與正被查詢的文檔不同的輸出文檔)的能力。XQuery 允許您在同一查詢中指定要搜尋的內容,并且指明應該采用什么樣的輸出格式。
下面是該查詢所操作的文檔的片段:
|
下面是我們希望產生的輸出文檔(進行了一些美化):
|
下面是查詢本身。它的工作是掃描所查詢的文檔中的所有圖書,生成上面所顯示的結果文檔:它在輸出的每個新 <book>
標簽中包含計算出的 authorCount
屬性;并放棄原始文檔中剩下的大部分信息,只保留每位作者的姓。
(請注意,我在這里使用了術語“所查詢的文檔”(單數)。這是一種簡化。XQuery 的數據模型也有能力處理文檔集。)
|
另外請注意,查詢本身不指定所要查詢的文檔或數據集上下文。這是所使用的特定查詢引擎確定的。
下面是該查詢的一些有趣特性:
for/let表達式
該示例包含兩個嵌套 的 for
循環和一個 let
。外部 for
迭代由擴展路徑表達式 //book 所得到每一個的節點,并將每個 <book>
節點隔離到名為 $book
的變量中。 let
表達式則取得每一本書的所有 <author>
子節點,并放到名為 $authors
的變量中。 $authors
變量包含一個節點 序列, $book
和 $author
變量都包含單節點。
請務必留意,這些變量不是 賦值的而是 綁定的。其中的差別很細微但卻很重要:一旦綁定了變量,它的值就不可更改。這可以防止在運行中對變量重新賦值而造成糟糕的負面影響。另一個潛在的好處是,可以(在某種程度上)在處理期間重排包含變量的行,從而允許智能引擎優化它們的查詢。
for
和 let
表達式是 FLWOR
(讀作 flower)表達式的子組件。 FLWOR
表達式的正式語法:
|
顯示它是一個有多種變化的表達式類型,可以生成大量不同的查詢實例。正如該產品所顯示的那樣,“ return
”關鍵字后面的 Expr
項本身可以被另一個 FLWOR
表達式替代,因此,可以像不斷加長的 LEGO 積木那樣,將 FLWR 表達式首尾相接,無限地排成一行。能夠用任何其他表達式類型替換 Expr
項,使 XQuery 具有 可編輯性并給予它豐富的表達能力。XQuery 中有大量表達式類型,在調用更通用的表達式時,可以將這些表達式插入到語法中。
一般情況下,最終是一個 return
語句終止 FLWOR
序列。在上面的查詢示例中,增加了一個內部 return
作為一個方便的插入點,插入要輸出的每個 <book> 的元素構造器。
這個查詢包含三個元素構造器。通過將文字尖括號 XML 直接寫入查詢本身的正文中,在查詢過程中動態生成元素 <results>、
<book>
和 <author>
。
在需要區分文字文本內容和元素構造器中需要判斷的子表達式時,使用花括號( { 和 })。例如,如果我們編寫如下所示的文字表達式則不需要用花括號來分隔內部標記和外部標記。:
|
順便提一句,花括號是在 2001年7月發布的表面語言語法中加入的。更早版本的語法就不需要它們。花括號是語言在成為 Recommendation(推薦標準)過程中不斷改變和發展的一個好例子。
下面一行
|
顯示了內置屬性構造器的用法。count() 函數返回每本書包含的 <author>
元素數。請再次注意花括號,它在這里用來包圍需要判斷的表達式。該規范的最后版本可能要求用引號分隔計算出來的屬性表達式,當前這兩種方法更是允許的。
count()
是內置函數的一個示例。“Functions and Operators”草案列出了14個不同組中接近250種函數和操作符,它們構造和操作各種不同的數據類型,包括數字、字符串、布爾值、日期和時間、qname、節點和序列。
在表達式中使用 text()
操作符
|
用從封閉的<last>元素中取得的姓氏的文本來填充每個 <author>
元素的內容。如果直接使用 $author/last
,就會將封閉的標簽也一并加入,在這里我們并不希望這樣。