2010-03-12 83 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