国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 開發(fā) > 綜合 > 正文

關(guān)于如何更新 XQuery 的具體步驟介紹

2024-07-21 02:39:53
字體:
供稿:網(wǎng)友
 更新XQuery
  XQuery有了一些新特性,內(nèi)容包括從原子化到跟蹤文件結(jié)構(gòu)。
  
  在"你所不了解的XQuery"(Oracle雜志,2003年5/6月刊)一文中,我介紹了XQuery,它是一項由萬維網(wǎng)聯(lián)盟(W3C)開發(fā)的技術(shù),設(shè)計用來查詢和操縱xml數(shù)據(jù)或任何能以XML形式出現(xiàn)的數(shù)據(jù),如關(guān)系型數(shù)據(jù)庫。那篇引文討論了2002年11月發(fā)布的XQuery草案規(guī)范。2003年5月,W3C發(fā)布了新的XQuery草案規(guī)范,本文追蹤報道了5月份發(fā)布的草案規(guī)范中最令人感愛好的變化和新增加的特性,其中包括庫模塊、序(PRolog)變量、外部函數(shù)以及用于調(diào)試、錯誤處理和格式化的新函數(shù)。
  
  變化
  5月草案增加了大量新特性,但是我首先討論對現(xiàn)有特性所做的更改。有些更改是表面上的。 例如,document()輸入函數(shù)(該函數(shù)使用給定的統(tǒng)一資源標(biāo)識符[URI]返回一個文檔)被改為一個新的更短的名字doc()。另外,曾經(jīng)被寫成{- comment -}的注釋現(xiàn)在改用新的笑臉符號(: comment :)。是的,現(xiàn)在每個注釋都成了一個笑話。
  
  有些更改則是更根本的。也許最重大的改動就是distinct-values()函數(shù)不再返回節(jié)點(節(jié)點是XML結(jié)構(gòu),如元素、文檔、注釋以及文本節(jié)點),它只返回原子值(如整數(shù)或字符串)。盡管該函數(shù)仍然接受節(jié)點和原子值,但只返回原子值。任何進入該函數(shù)的節(jié)點都會被"原子化"并被當(dāng)作原子值,然后以原子形式返回。
  
  原子化的規(guī)則很復(fù)雜,這里給出一些基本的:由模式定義為布爾型的元素將被原子化為true/false布爾值。定義為整型的元素將被原子化為一個整數(shù)。沒有被模式定義的元素將被原子化為節(jié)點的XPath字符串值(文本節(jié)點遞歸地連接在一起)。
  
  為了說明:
  distinct-values(<item>apple</item>,
  <item>banana</item>, "grape")
  
  返回值("apple","banana","grape"),假設(shè)在模式中沒有聲明 。在下面的例子中,假如我們假設(shè) 被模式定義為布爾型,那么下面的語句:
  
  distinct-values(<status>0</status>,
  <status>false</status>)
  
  返回false(),因為它是兩個元素的原子值。記住false()是XQuery常量,表示"假"。
  
  現(xiàn)在你也許會想,"當(dāng)我想返回節(jié)點時,可以使用distinct-nodes()函數(shù)。" 是的,但該函數(shù)只能根據(jù)節(jié)點標(biāo)識刪除重復(fù)節(jié)點(那些完全相同的節(jié)點,類似于java中引用的等效節(jié)點)。沒有能刪除等效節(jié)點的函數(shù)。這會使查詢變得復(fù)雜,因為沒有辦法能輕松地刪除等效節(jié)點。
  
  回過頭來看我以前的那篇文章"你所不了解的XQuery",你將發(fā)現(xiàn)有些示例會受到這一改動的影響。在那篇文章中,下面的查詢返回了藝術(shù)家名字的惟一列表,其中每一個名字前后都帶有 標(biāo)記:
  
  distinct-values(document("itunes.xml")
  /itunes/Tracks/Track/Artist)
  
  示例輸出類似于:
  
  <Artist>Marc Cohn</Artist>
  <Artist>Pink Floyd</Artist>
  
  現(xiàn)在,執(zhí)行同樣的查詢則返回原子值:
  
  Marc Cohn
  Pink Floyd
  
  由于distinct-values()去掉了 標(biāo)記(這是原子化過程的一部分),所以你必須在完成distinct-values()調(diào)用后添加標(biāo)記,如下所示:
  
  let $artists :=
  distinct-values(doc("itunes.xml")
  /itunes/Tracks/Track/Artist)
  for $a in $artists
  return <Artist>{ $a }</Artist>
  
  不是每種情況都是這么輕松地得到處理。看一下W3C 使用案例文檔中的示例1.1.9.4在2002年11月版與2003年5月版中是如何變化的。該示例返回每位作者的著作列表。它使用了distinct-values(),根據(jù)2002年11月的規(guī)范,它的代碼如下:
  
  <results>
  {
  for $a in distinct-values(
  document("http://www.bn.com/bib.xml")
  //author)
  return
  <result>
  { $a }
  {
  for $b in document(
  "http://www.bn.com/bib.xml")
  /bib/book
  where some $ba in $b/author
  satisfies deep-equal($ba,$a)
  
  ; return $b/title
  }
  </result>
  }
  </results>
  
  根據(jù)查詢結(jié)果你不能直接分辨出姓和名,但每個 元素都由一個 和 名組成。distinct-values()調(diào)用返回具有惟一名字的 元素列表。對于2003年5月的規(guī)范,現(xiàn)在查詢必須在姓和名上單獨運行distinct-values(),而且在嵌套的FLWOR表達式中也沒有將$a指定為惟一的作者:
  
  <results>
  {
  let $a :=
  doc("http://www.bn.com/bib/bib.xml")
  //author
  for $last in distinct-values($a/last),
  $first in distinct-values(
  $a[last=$last]/first)
  return
  <result>
  { $last, $first }
  {
  for $b in
  doc("http://www.bn.com/bib.xml")
  /bib/book
  where some $ba in $b/author
  satisfies ($ba/last = $last and
  $ba/first=$first)
  return $b/title
  }
  </result>
  }
  </results>
  
  除了編寫用戶定義的distinct-deep-equal()外,沒有更好的方法來完成這件事了,而該方法在純XQuery中不能執(zhí)行。(注:FLWOR(發(fā)音為"flower")表達式是XQuery的構(gòu)建模塊。這個名字來源于組成表達式的要害詞For、Let、Where、Order by和Return}。
  
  新函數(shù)
  2003年5月的XQuery規(guī)范草案增加了三個新函數(shù),它們肯定會非常有用。第一個是:
  
  trace($value as item()*,
  $label as xs:string) as item()*
  
  trace()函數(shù)答應(yīng)在查詢的中間進行printf風(fēng)格的調(diào)試。該函數(shù)有兩個參數(shù):要顯示的值(可以是任意多個項的序列)以及要顯示的這個值的字符串標(biāo)簽。為方便起見,函數(shù)返回$value傳遞的值。trace()輸出的位置由你的引擎來決定。
  
  該函數(shù)使你能夠具體查看查詢的內(nèi)部過程。例如,下面的查詢根據(jù)文檔名返回在XQuery引擎中存儲的所有文檔的URI。通過增加一個trace()調(diào)用,我能夠在排序前查看返回的每個URI:
  
  define function uris() as xs:string* {
  for $n in input()
  return trace(
  xs:string(document-uri($n)), "base:")
  }
  for $u in uris() order by $u return $u
  
  輸出結(jié)果可能如下:
  
  2003-08-01 14:40:46 base: census.xml
  2003-08-01 14:40:46 base: ipo.xml
  
  當(dāng)使用trace()和其他類似的函數(shù)時,記住在XQuery中每項內(nèi)容都是一個表達式。沒有語句!為了能夠完成類似語句的操作,你可以采用在表達式之間加逗號的方法來創(chuàng)建一個序列。然后,單獨計算每個表達式的值。在最終的結(jié)果序列中忽略所有返回空值的表達式。例如,下面是兩個不影響結(jié)果的trace()調(diào)用:
  
  trace((), "starting query"),
  
  let $time := current-dateTime()
  let $ignored := trace($time, "Got time")
  return
  <Html>
  <head></head>
  <body>Current time is { $time }</body>
  </html>
  
  請注重第一個trace()調(diào)用后面的逗號。它使查詢返回一個具有兩個項的序列,第一個trace()調(diào)用的結(jié)果為空,因而被忽略。一般人不了解這一情況,但高級查詢實際上就是返回一個序列,因此在這種非凡情況下兩端的括號不是必需的。查詢"5, "是完全正確的。此外,在這個示例中你會看到,當(dāng)編寫一個FLWOR表達式時,你可以執(zhí)行l(wèi)et子句右側(cè)的任意代碼,并且忽略該值。
  
  5月份的草案還增加了error()函數(shù):
  
  error($srcval as item()?)
  
  這個函數(shù)使用戶能夠報告一個錯誤,類似于拋出一個異常。$srcval被定義為item()?,意味著它可以是一個XML結(jié)構(gòu)或原子,并且加上問號標(biāo)記表示這是可選的。下面是一些示例應(yīng)用:
  
  error()
  error("Missing source document")
  error(<span>A <i>beautifully</i>
  formatted error</span>)
  
  error()調(diào)用就像發(fā)生異常時那樣展開堆棧。遺憾的是,XQuery仍沒有try/catch功能。因此,盡管你能拋出錯誤,但卻不能從中恢復(fù)。
  
  在5月份的草案中最后一個引人注目的新增函數(shù)有一個希奇的名字:round-half-to-even()。它有兩種形式:
  
  round-half-to-even($srcval as numeric?)
  as numeric?
  round-half-to-even($srcval as numeric?,
  $precision as xs:integer) as numeric?
  
  在有一個參數(shù)的情況下,它的行為類似于round()函數(shù),只是當(dāng)一個數(shù)恰好落在其他兩個數(shù)的中間時,它將參數(shù)取整為最接近的偶數(shù)值。數(shù)字理論家們會告訴你從統(tǒng)計學(xué)上講這是一個更精確的取整算法。舉例說明:
  
  round-half-to-even(1.5) = 2.0
  round-half-to-even(2.5) = 2.0
  round-half-to-even(2.51) = 3.0
  
  有第二個參數(shù)的情況使函數(shù)變得很有趣。第二個參數(shù)表示精確級,并答應(yīng)將函數(shù)用于格式化小數(shù)值。例如:
  
  round-half-to-even(3.567, 2) = 3.57
  round-half-to-even(1113.567, -2) = 1100.0
  round-half-to-even(1 div 9, 3) = 0.111
  
  在聲明中使用的數(shù)字數(shù)據(jù)類型是xs:decimal、xs:integer、xs:float、xs:double以及任何根據(jù)限制由它們導(dǎo)出的類型的一種簡單表示。它用于XQuery規(guī)范中,但你不能在自己的查詢中使用它。
  
  新的查詢文件結(jié)構(gòu)
  2003年5月的草案中最重要的修改包括XQuery文件結(jié)構(gòu)。草案引入了主模塊和庫模塊的概念,并利用它們添加了從可重用組件中構(gòu)建查詢所急需的功能。該草案還擴展了查詢序(query prolog),從而提供了大量特性,如可選的版本聲明、新的聲明、新的導(dǎo)入、變量的外部定義以及函數(shù)的定義等。
  
  序類似于(由于邊界的限制,有時字符串寫在兩行上):
  
  module "http://www.w3.org/2003/05/
  xpath-functions"
  
  default element namespace=
  "http://www.w3.org/1999/xhtml"
  declare namespace xs=
  "http://www.w3.org/2001/XMLSchema"
  
  import module
  "http://www.w3.org/2003/05/
  xpath-functions" at "logo.xq"
  
  define function addLogo(
  $root as node()) as node()* { }
  
  (: etc :)
  
  通過查看從5月份的規(guī)范中借用的巴科斯-諾爾范式(Backus Naur Form ,BNF),我可以描述得更精確一些:
  
  Module    ::= MainModule
  LibraryModule
  MainModule  ::= Prolog QueryBody
  LibraryModule ::= ModuleDecl Prolog
  ModuleDecl  ::= "module" StringLiteral
  Prolog    ::= Version? (NamespaceDecl
   XMLSpaceDecl
   DefaultNamespaceDecl
   DefaultCollationDecl
   SchemaImport
   ModuleImport
   VarDefn
   ValidationDecl)*
  FunctionDefn*
  QueryBody   ::= Expr
  
  不論你什么時候試圖理解一種語言或文件格式的結(jié)構(gòu),能夠閱讀BNF都很重要。元符號"::="表示"被定義為",""表示"或",修飾符"?"、"+"和"*"分別表示0或1、1或更多以及0或更多。
  
  該BNF表明每個模塊由一個MainModule或一個LibraryModule組成。MainModule是一個后面帶QueryBody的序,而LibraryModule則是一個ModuleDecl,其后為一個不帶QueryBody的序。ModuleDecl由字符串"module"打頭,然后是StringLiteral,本例中它恰好是一個URI。一個序由一個可選的初始版本以及其后的各種聲明、導(dǎo)入和多個順序不限的定義組成。在這之后是數(shù)量不限的函數(shù)定義。最后,以前在MainModule中引用的QueryBody被定義為一個單一的Expr表達式。Expr以及其他非終結(jié)符號的定義可以在規(guī)范的其他地方找到。
  
  我在這里說明BNF是因為這是理解新的查詢文件結(jié)構(gòu)最準(zhǔn)確的方法,并且當(dāng)有些查詢不能像期望的那樣運行而不得不求助于規(guī)范時,它還會提供極為有用的幫助。
  
  在序中首先應(yīng)該是Version(版本)。一個XQuery模塊可以在序的開始部分聲明它的版本號。Version指明了XQuery的版本,根據(jù)這個版本設(shè)計代碼來運行查詢。當(dāng)碰到一個未知的版本時,處理程序可以拋出一個錯誤。沒有版本聲明語句則隱含額版本號為"1.0"。遺憾的是,眾多預(yù)發(fā)布的草案不能使用版本,所以該特性現(xiàn)在還不會提供什么幫助。版本聲明類似于:
  
  module "http://www.w3.org/2003/05/
  xpath-functions"
  xquery version "1.0"
  
  (: etc :)
  
  請注重BNF是如何說明版本聲明必須永遠跟在模塊聲明后面的。
  
  命名空間
  為了理解XQuery的其他組件,首先理解XML的命名空間非常重要,其中包括多數(shù)人忽略的一些細節(jié)。傳統(tǒng)上,XML命名空間答應(yīng)具有相同本地名(例如 <table>)的元素具有不同的語法含義。命名空間由URI指定,如http://www.w3.org/1999/xhtml指定一個HTML表,http://furnitureworld.com指定一個四條腿的桌子。雖然它們看起來像HTTP URL,但命名空間只是一些含糊的名字。它們與HTTP協(xié)議完全無關(guān),而且雖然在Web上的那個URL可能會有一些內(nèi)容,但并不是一定要有內(nèi)容!命名空間由前綴"http://"打頭只是由W3C開始的,已經(jīng)成為一個慣例,事實上可以使用任何前綴。
  
  的確,這很令人費解。假如命名空間不是根據(jù)URI標(biāo)準(zhǔn)化,如ns:org.w3.1999.xhtml,也許會更輕易理解一些。
  
  XML元素和屬性總是與命名空間相關(guān)聯(lián),即使只是一個不存在的命名空間。非凡的xmlns屬性聲明一個命名空間前綴別名,用來將元素放到命名空間中。別名在聲明xmlns屬性的元素的范圍內(nèi)(可用),所有屬性和元素都保留在這個元素中。在這個范圍內(nèi),任何使用該前綴的元素或?qū)傩远急徽J為是在與該別名相關(guān)聯(lián)的命名空間中。例如,下面的代碼在命名空間中有三個節(jié)點:
  
  <xhtml:table
  xmlns:xhtml=
  "http://www.w3.org/1999/xhtml"
  xmlns:xlink=
  "http://www.w3.org/1999/xlink">
  <xhtml:tr width="200" xlink:href="#x">
  <xhtml:td/>
  </xhtml:tr>
  </xhtml:table>
  
  表元素聲明了兩個命名空間別名:xhtml和xlink,它們與兩個不同的標(biāo)準(zhǔn)URI相關(guān)聯(lián)。<table>、<tr>和<td> 元素被放在命名空間http://www.w3.org/1999/xhtml中,而href屬性被放在命名空間http://www.w3.org/1999/xlin
  k中。width屬性在前面提到的不存在的命名空間(即第三個命名空間)中。請記住,命名空間的重要組成部分是URI,而不是前綴別名,假如元素的URI相匹配,則它們被認為是在同一個命名空間中,盡管它們的前綴別名可能不同。
  
  "默認的命名空間"是不帶前綴的元素使用的命名空間。它由不包括前綴的非凡xmlns屬性來分配。默認的命名空間在元素的范圍內(nèi)有效,并請求該元素及其內(nèi)容,而且會對這個范圍內(nèi)的所有無前綴的元素起作用。但是,默認的命名空間對無前綴的屬性不起作用。來看下面這個例子:
  
  <table
  xmlns="http://www.w3.org/1999/xhtml"
  xmlns:xlink=
  "http://www.w3.org/1999/xlink">
  <tr width="200" xlink:href="#x">
  <td/>
  </tr>
  </table>
  
  這個XML在語法上等同于前面所示的XML。原來別名為"xhtml"的命名空間現(xiàn)在變成了默認的命名空間,并應(yīng)用到<table>元素內(nèi)所有無前綴的元素。因此<table>、<tr>和<td>元素仍在命名空間http://www.w3.org/1999/xhtml中。href屬性仍在命名空間http://www.w3.org/1999/xlink中。而且由于無前綴的屬性不在默認的命名空間中,所以width屬性仍在不存在的命名空間中。
  
  缺少的命名空間可以用空的字符串URI來表示。這樣就可以直接放到不存在的命名空間中了。例如:
  
  <table xmlns="http://www.w3.org/1999/xhtml">
  <tr> <td/> </tr>
  <data xmlns=""> <subdata/> </data>
  </table>
  
  這里的<table>、<tr>和<td>元素存放在默認的命名空間即http://www.w3.org/1999/xhtml中,而數(shù)據(jù)和子數(shù)據(jù)元素則存放在不存在的命名空間中。
  
  在XQuery中,編寫XML代碼時你可以使用標(biāo)準(zhǔn)的命名空間聲明和規(guī)則:
  
  let $bug :=
  <x:bug xmlns:x="http://www.bug.com/ns">
  <x:desc>Order entry fails</x:desc>
  </x:bug>
  
  或者,你可以在序中聲明一個命名空間別名:
  
  declare namespace x =
  "http://www.bug.com/ns"
  let $bug :=
  <x:bug>
  <x:desc>Order entry fails</x:desc>
  </x:bug>
  
  你還可以在序中聲明一個默認的元素命名空間:
  
  default element namespace =
  "http://www.bug.com/ns"
  declare namespace xhtml =
  "http://www.w3.org/1999/xhtml"
  
  let $bug :=
  <bug>
  <desc>Order entry fails</desc>
  </bug>
  let $report :=
  <xhtml:span>{$bug}</xhtml:span>
  
  當(dāng)使用默認的元素命名空間時,無論是用xmlns屬性還是用聲明語句聲明,你都必須小心。路徑表達式會受到它們所處位置范圍內(nèi)的命名空間的影響。在XQuery中,輸入和輸出命名空間沒有區(qū)別。要理解為什么會發(fā)生這種情況,請先設(shè)法確定下面這條查詢是否運行:
  
  let $bug :=
  <bug xmlns="http://www.bug.com/ns">
  <desc>Order entry fails</desc>
  <cause>{ input()/bugdb
  //item[@id="123"] }
  </cause>
  </bug>
  為了讓它運行, 和 元素必須放在哪個命名空間中?id屬性呢?答案是,由于路徑表達式/bugdb//item[@id="123"]出現(xiàn)在默認元素命名空間http://www.bug.com/ns的范圍內(nèi),所以在這個命名空間中執(zhí)行無前綴路徑表達式組件。這可能正確,也可能不正確。為了使這個查詢能夠運行,bugdb和item必須在http://www.bug.com/ns命名空間中。id屬性不受默認元素命名空間的影響,因為它是一個屬性。前面的查詢跟下面這個查詢一樣:
  
  let $bug :=
  <x:bug xmlns:x="http://www.bug.com/ns">
  <x:desc>Order entry fails</x:desc>
  <x:cause>{ input()/x:bugdb
  //x:item[@id="123"] }
  </x:cause>
  </x:bug>
  
  在生成XHTML內(nèi)容時經(jīng)常出現(xiàn)這個問題。Microsoft Internet Explorer瀏覽器不理解帶前綴的XHTML,而是使用具有默認元素命名空間的無前綴XHTML來影響所有在XHTML內(nèi)容中出現(xiàn)的查詢。避免這個問題的一種方法就是在默認元素范圍外寫一些函數(shù),如下所示:
  
  define function get-body() as element() {
  doc("test.xml")/body
  }
  
  <html xmlns="http://www.w3.org/1999/xhtml">
  <head/>
  { get-body() }
  </html>
  
  另一種方法是為不存在的命名空間顯式地聲明一個前綴,如下所示:
  
  declare namespace e = ""
  
  <html xmlns="http://www.w3.org/1999/xhtml">
  <head/>
  { doc("test.xml")/e:body }
  </html>
  
  函數(shù)命名空間
  XQuery預(yù)定義了5個命名空間前綴:
  
  xml
  http://www.w3.org/XML/1998/namespace
  xs
  http://www.w3.org/2001/XMLSchema
  xsi
  http://www.w3.org/2001/XMLSchema-instance
  fn
  http://www.w3.org/2003/05/xpath-functions
  xdt
  http://www.w3.org/2003/05/xpath-datatypes
  
  XML(xml)、XML模式(xs)和XML模式實例(xsi)是XML命名空間和XML模式標(biāo)準(zhǔn)。5月份的XQuery草案引入了最后兩個標(biāo)準(zhǔn)--XPath函數(shù)(fn)和XPath數(shù)據(jù)類型(xdt)。
  
  默認函數(shù)命名空間是http://www.w3.org/2003/05/XPath-functions,使用標(biāo)準(zhǔn)的"fn"默認前綴。你可以更改這個命名空間,但是你必須使用內(nèi)置的"fn"前綴來限定任何內(nèi)置的函數(shù)調(diào)用。例如:
  
  default function namespace =
  "http://example.com/functions"
  fn:string-length("foo")
  
  導(dǎo)入模塊將函數(shù)和變量(也只能是函數(shù)和變量)從外部庫模塊加載到主模塊中。在進行模塊導(dǎo)入時,你應(yīng)該指定一個目標(biāo)命名空間,它需要與模塊中聲明的命名空間相匹配。這類似于導(dǎo)入一個Java包,其中導(dǎo)入語句路徑必須與包語句的路徑相匹配。在導(dǎo)入
  過程中,你還可以指定加載模塊的位置,這個位置以URI的形式給出。任何函數(shù)或變量名的沖突都會拋出一個錯誤。下面是common.xq庫模塊文件以及隨后的main.xq主模塊文件:
  
  (: common.xq file :)
  module "http://www.w3.org/2003/05/
  xpath-functions"
  
  define function uris() as xs:string* {
  for $n in input()
  return xs:string(document-uri($n))
  }
  (: no body allowed in library modules :)
  
  
  (: main.xq file :)
  import module
  "http://www.w3.org/2003/05/
  xpath-functions" at "common.xq"
  
  uris()
  
  common.xq文件(XQuery文件的標(biāo)準(zhǔn)擴展名還沒有確定)包含前面給出的uris()函數(shù)的定義。利用這個聲明,該文件把它的函數(shù)放在了http://www.w3.org/ 2003/ 05/XPath-functions命名空間中。main.xq文件用同樣的命名空間導(dǎo)入模塊。由于uris()函數(shù)存放在默認的函數(shù)命名空間中,所以main.xq可以調(diào)用不帶前綴的uris()。
  
  在默認的命名空間中寫函數(shù)非常方便,而且意味著你不必給你的調(diào)用加前綴。但是,high-profile模塊應(yīng)該使用另一個命名空間以避免沖突。我建議像看待Java默認包那樣看待"fn"命名空間:它對構(gòu)造原型很有用,但對已完成的庫模塊卻沒什么用途。要想加載帶有另一個前綴的模塊,可以這樣做:
  
  import module namespace x="ns://foo" at "common.xq"
  x:uris()
  
  當(dāng)然,common.xq必須聲明同一個命名空間。為了保證導(dǎo)入成功,兩邊必須一致,就像Java包一樣。
  
  請記住,在這些導(dǎo)入中,"common.xq"URI并不是指一個文件路徑--它只是一個含糊的名字,服務(wù)器將它以某種方式映射為common.xq內(nèi)容。規(guī)范對將URI映射為資源并沒有太多強制要求,因為查詢不會總存在于文件中。
  
  函數(shù)還可以有"外部"聲明。外部聲明說明函數(shù)必須由系統(tǒng)提供。假如系統(tǒng)不提供外部聲明,就會出錯。這一特性使在外部用非XQuery語言--也許是Java語言編寫支持代碼成為可能。通過在查詢中聲明外部函數(shù),引擎的靜態(tài)分析可以確保函數(shù)存在于外部,而且在開始查詢前得到正確簽名。外部函數(shù)在函數(shù)體內(nèi)使用要害字"external"。例如:
  
  define function sort($elts as element()*)
  as element()* external
  
  sort((<c/>, <a/>, <b/>))
  
  這個外部函數(shù)對一序列元素進行排序。執(zhí)行排序過程可能是用另一種語言,或由引擎另外提供。向外部環(huán)境傳遞狀態(tài)或從外部環(huán)境傳遞狀態(tài)的準(zhǔn)確語法目前還沒有確定。一旦這些語法被廣泛采用,查明到底是Java代碼利用XQuery調(diào)用更普遍還是XQuery代碼利用Java調(diào)用更普遍將是非常有趣的。
  
  序變量
  你還可以在序中聲明和定義變量。假如沒有提供變量類型的話,那么變量類型是可選的,并且可以推斷出來。值要放在大括號內(nèi)。例如:
  
  define variable $x as xs:integer {7}
  define variable $y {7.5}
  (: infer xs:double here :)
  
  在序中聲明變量對單獨的一個查詢沒什么意義,但對導(dǎo)入的模塊遲早會有用。前面說過導(dǎo)入的模塊向主模塊提供了函數(shù)和變量定義。這使得序變量可以用作全局常量:
  
  module "http://x-query.com/math"
  define variable $PI as xs:decimal
  { 3.1415926535897932384626433 }
  
  一個變量還可以被標(biāo)記為"external",以說明它的值來自外部環(huán)境。這就使存儲過程參數(shù)傳遞和改變輸入源成為可能。例如:
  
  define variable $input
  as item()* external
  define variable $quantity
  as xs:integer external
  
  $input/item[quantity >= $quantity]
  
  結(jié)論
  2003年5月的XQuery草案引入了一些新的重要特性--從像trace()和error()這樣的簡單的新實用方法到諸如庫模塊、函數(shù)命名空間、序變量以及外部函數(shù)和變量等重要的改動。過去,大多數(shù)供給商都要花一些時間來升級他們的XQuery引擎以支持每個新版本,所以你要意識到這里給出的示例代碼不一定立即適用于每個引擎。為了幫助你跟蹤查詢情況,我和Mike Clark創(chuàng)建了一個XQuery測試工具,叫做BumbleBee。該工具類似于XQuery的JUnit。它包含了一組標(biāo)準(zhǔn)測試查詢,并使你能夠編寫自己的查詢。對于那些對測試驅(qū)動的開發(fā)著迷的人來說,BumbleBee是一個非常棒的工
  
  具。你可以先寫示例輸入和期望的輸出,然后寫查詢。每進行一次升級,就測試一次你的查詢,以確保它仍能正常運行。你可以在xquery.com/bumblebee上找到BumbleBee。
  
  Jason Hunter (jasonhunter@servlets.com) )是一名顧問,他是《Java 編程》一書的作者、《Java 企業(yè)最佳實踐》一書的合著者(這兩本書均由O'Reilly & Associates出版公司出版)以及Servlets.com的發(fā)行人。
  
  XQJ
  在2003年5月的XQuery草案中沒有引入但幾乎同時公布的是一個來自O(shè)racle和IBM的提議,即創(chuàng)建一個用于XQuery/Java交互的通用API。因為JDBC是用于SQL的,所以這個API將用于XQuery。提議已被提交給Sun公司的Java社區(qū)進程(Java Community Process ,JCP)組織,并被該組織接受,作為JSR-225,名為"XQuery API for(用于Java的XQuery API,XQJ)"。該API很可能存在于javax.xml.XQuery包中。
  
  JSR確定的目標(biāo)中包括:
  
  與JDBC和用于XML處理的Java API(JAXP)在格式上類似;
  
  提供事務(wù)性支持的面向連接的界面(因為XQuery 1.0不會有標(biāo)準(zhǔn)的更新機制,所以這一點令人很感愛好);
  
  單次查詢的無連接界面;
  
  能夠從JDBC連接中創(chuàng)建對引擎有意義的XQJ連接;
  
  能夠為重復(fù)執(zhí)行而編譯查詢;
  
  支持參數(shù)化查詢和輸入?yún)?shù)的發(fā)現(xiàn)/綁定;
  
  支持使用JAXP和用于XML的流式API(Streaming API for XML,StAX)處理結(jié)果;
  
  T能夠處理包括一般序列在內(nèi)的任何合法結(jié)果。
  
  能夠使查詢結(jié)果序列化。
  
  事實終將證實,JSR對Java和J2EE程序員是極為有用的。現(xiàn)在,供給商必須創(chuàng)建用來與XQuery引擎交互的定制的API,只有最好的引擎才會熟悉到結(jié)果可以是任意順序的項,而不是單獨的XML文檔。使用這個JSR會強化行為的規(guī)范性,另外還會提供輕松的后端可插拔性。
    


發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 汾西县| 怀安县| 嘉兴市| 当雄县| 阳谷县| 井冈山市| 淮南市| 台山市| 政和县| 灵武市| 桦川县| 安陆市| 龙里县| 新龙县| 宁武县| 扶风县| 保山市| 三亚市| 甘泉县| 桃源县| 泊头市| 宜春市| 太仆寺旗| 泾川县| 兴义市| 道真| 乌拉特前旗| 崇义县| 浠水县| 布拖县| 舞钢市| 临桂县| 古田县| 屏边| 玉溪市| 太谷县| 攀枝花市| 车险| 阜宁县| 宁化县| 鸡东县|