如何在MarkLogic XQuery中编写while循环

如何在MarkLogic XQuery中编写while循环,xquery,marklogic,Xquery,Marklogic,在MarkLogic XQuery中编写等价的while循环有没有公认的习惯用法?我知道我可以编写一个尾部递归例程,但是MarkLogic XQuery没有优化尾部递归,而且我得到了堆栈溢出(我必须循环20000次) 编辑注:从MarkLogic 6开始,尾部递归在MarkLogic中进行了优化。在XQuery中通常使用FLWOR表达式。如何编写它在很大程度上取决于您的循环和数据,因为它不是指向其他语言已知的while循环的Exact映射 所以你能做的就是 let $c := doc('my.d

在MarkLogic XQuery中编写等价的while循环有没有公认的习惯用法?我知道我可以编写一个尾部递归例程,但是MarkLogic XQuery没有优化尾部递归,而且我得到了堆栈溢出(我必须循环20000次)


编辑注:从MarkLogic 6开始,尾部递归在MarkLogic中进行了优化。

在XQuery中通常使用FLWOR表达式。如何编写它在很大程度上取决于您的循环和数据,因为它不是指向其他语言已知的while循环的Exact映射

所以你能做的就是

let $c := doc('my.doc')/root/get-all-my-elements-using-xpath
return process-result($c)

如果您需要进一步的建议,请更具体地说明您实际想要做什么。

递归是常用的方法。另一种方法是将FLWOR与
try catch
一起使用,并抛出一个包含已知代码的异常以提前退出

try {
  for $x in 1 to count($tokens)
  return tok($x) }
catch ($ex) {
  if ($x/error:code eq 'BREAK') then ()
  else xdmp:rethrow() }
tok
函数将调用
error((),'BREAK')
退出父FLWOR表达式。如果需要,您可以将令牌计数乘以某个因子,或者使用任意大的数字


有一个更复杂的例子,在
封面:actual via debug
函数中。

我认为您最好重新考虑您的逻辑。你想达到什么目标?也许有更好的方法来做你尝试的事情。迭代20k次听起来不太合适。我正在编写一个递归下降解析器,用于将字符串转换为XML,但实际上我也对任何通用习惯用法感兴趣,可能使用一些MarkLogic扩展。如果你有语法,你可以省去编写解析器。将它提交给这个REx解析器,并选择XQuery输出:@grtjn编写解析器并不困难,它是一个非常简单的语法。问题在于产生的递归代码。我会看看REx,但如果它输出传统的递归代码,我的情况也不会比以前好。MarkLogic 6支持尾部调用优化-也许你可以试试。谢谢,但我想到的是,在没有可以迭代的序列的情况下。显然,如果我有这样一个序列,我会使用flower表达式。MarkLogic 6支持XQuery 3.0 try/catch,它允许您在调用fn:error()函数时检索传递给它的任意参数值。通过这种方式,您可以提前终止循环,并且仍然返回一个值。