2010-03-12 117 views
2

即時通訊新的項目,我要寫,我認爲是一件簡單的事情。一個遞歸函數,它將嵌套的xml元素寫入x個級別(用變量表示)。到目前爲止,我已經提出了這個問題,但不斷收到編譯錯誤。請注意,我有可能產生新的XML,無法查詢現有的XML:XQuery - 遞歸函數的問題

xquery version "1.0"; 

    declare function local:PrintTest($amount) 
    { 
     <test> 
     { 
     let $counter := 0 
     if ($counter <= $amount) 
      then local:PrintTest($counter) 
      else return 
     $counter := $counter +1 
     } 
     </test> 
    }; 

local:PrintPerson(3) 

我的錯誤是:

File Untitled1.xquery: XQuery transformation failed 
    XQuery Execution Error! 
Unexpected token - " ($counter <= $amount) t" 

我永遠無法理解的XQuery,並且不能很明白這是爲什麼不工作(是隻是我還是在互聯網上關於XQuery的資源非常少?)

回答

6

您已經以程序化的方式編寫了該函數,XQuery是一種功能語言。

每個函數體只能是單個表達式;它看起來像你正在試圖編寫語句(這在XQuery中不存在)。

首先,let表達式後面必須跟一個return關鍵字。

return僅用作FLWOR表達式的一部分,函數總是計算一個值。正如你所寫的那樣return相當於/return,所以會返回一個叫做return的節點。

$counter := $counter + 1根本無效。您只能使用let表達式設置一個像這樣的變量,在這種情況下,它會創建一個名爲counter的新變量,替換舊變量,該變量在變量的返回表達式中僅在的範圍內

正確的方法做你正在嘗試做的是減少$論證的每次遞歸函數值,並停止當你打0

declare function local:Test($amount) 
{ 
    if ($amount == 0) 
    then() 
    else 
    <test> 
     { 
     local:Test($amount - 1) 
     } 
    </test> 
}; 

local:Test(3) 

請注意,我已經改變了名稱的功能進行測試。名稱「PrintTest」是誤導性的,因爲這意味着函數做了某些事情(即打印)。該功能實際上只是返回一個節點,它不會進行任何打印。在一個純粹的函數式語言中(XQuery非常接近),一個函數從來沒有任何副作用,它只是返回一個值(或者在這個例子中是一個節點)。

+0

歡呼聲,不得不讓我的頭纏住這個 – 2010-03-15 17:28:38