XQuery/高階函式
您有一個專案序列,並且想要對序列中的每個專案執行一系列連續的操作。
您希望使用單個函式,並將一系列函式作為引數傳遞給該函式。
函式式語言是將函式視為一等資料型別的語言。它們通常有一個函式,允許您傳遞一個專案列表並告訴它對這些專案中的每一個執行什麼函式。就像 XML 轉換一樣,當您需要對大量專案執行許多小型任務時,函式式語言是理想選擇。函式式語言非常適合這些任務,因為實際執行函式的順序並不需要保證。開發人員不必擔心在系統開始處理專案 2 之前等待對專案 1 的轉換完成。
Google 的 MapReduce 演算法是函式式系統的示例。MapReduce 允許將資料集(例如“所有網站”)視為專案序列。MapReduce 然後有不同的處理器,每個處理器接收可以獨立處理的小工作項。
有關函式式語言的更多資訊,請參閱 維基百科上的函數語言程式設計 和 Wikibooks 上的函數語言程式設計。
因為 XQuery 也是一種函式式語言,所以您也可以確信,傳遞給 XQuery 函式的大量專案列表可以獨立地在許多處理器上執行,而不用擔心如果專案亂序處理會導致結果錯誤。
在以下示例中,我們將宣告兩個函式。然後,我們將透過將這些函式應用於序列中的每個專案來處理單詞列表。我們將透過將函式名作為引數傳遞給另一個函式來實現這一點。
注意:這似乎只在 eXist 1.3 中有效。eXist 版本 1.2.X 與 QName() 函式關聯了錯誤的資料型別。
eXist 系統需要將每個函式轉換為函式識別符號。為此,它需要呼叫 util:function()。util:function 接受兩個引數,函式的限定名稱(字首和函式名)以及函式的元數。在本例中,函式的 元數 是函式接受的引數數量。第一個引數的資料型別必須為 QName 型別。第二個引數(元數)的資料型別為整數。
util:function($function as xs:QName, $arity as xs:integer) as function
declare namespace fw = "http://www.cems.uwe.ac.uk/xmlwiki/fw";
declare function fw:apply($words as xs:string*, $my-function function(item()) as item()) {
for $word in $words
return util:call($my-function,$word)
};
declare function fw:f1($string) {
string-length($string)
};
declare function fw:f2($string) {
substring($string,1,1)
};
let $f1 := util:function(QName("http://www.cems.uwe.ac.uk/xmlwiki/fw","fw:f1"),1)
let $mywords := ("red","green","purple")
return
<hofs>
<data>{$mywords}</data>
<hof>
<task>length of each string</task>
<result>{fw:apply($mywords,$f1)}</result>
</hof>
<hof>
<task>Initial letter of each string</task>
<result>{ fw:apply($mywords, util:function(QName("http://www.cems.uwe.ac.uk/xmlwiki/fw","fw:f2"),1) ) }</result>
</hof>
</hofs>