XQuery - 递归函数的问题

Bri*_*ard 2 xquery

我是这个项目的新人,我要写,我认为这是一件简单的事情.一种递归函数,用于将嵌套的xml元素写入x级别(由变量表示).到目前为止,我已经提出了这个问题,但一直遇到编译错误.请注意,我必须生成新的xml,而不是查询现有的xml:

    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)
Run Code Online (Sandbox Code Playgroud)

我的错误是:

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

我从来不理解xquery,并且不能完全明白为什么这不起作用(仅仅是我还是在互联网上关于XQuery的资源非常少?)

Oli*_*lam 6

您已经以程序方式编写了此函数,XQuery是一种函数式语言.

每个函数体只能是一个表达式; 看起来你正在尝试编写语句(XQuery中不存在).

首先,let表达式后面必须跟一个return关键字.

return仅用作FLWOR表达式的一部分,函数始终求值为一个值.正如您所写,它return等同于/return将返回一个名为return的节点.

该行$counter := $counter + 1根本不是有效的XQuery.您只能使用let表达式设置这样的变量,在这种情况下,它将创建一个名为counter的新变量,该变量将替换旧变量,该变量在变量的返回表达式中位于范围内.

执行您要执行的操作的正确方法是每次函数递归时减少$参数的值,并在达到0时停止.

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

local:Test(3)
Run Code Online (Sandbox Code Playgroud)

请注意,我已将函数的名称更改为Test.名称"PrintTest"具有误导性,因为这意味着该功能可以执行某些操作(即打印).该函数实际上只返回一个节点,它不进行任何打印.在一个纯函数语言(XQuery非常接近)中,函数从不会产生任何副作用,它只返回一个值(或者在这种情况下是一个节点).