XQuery - проблема с рекурсивной функцией - PullRequest
2 голосов
/ 12 марта 2010

Я новичок в этом проекте и собираюсь написать, что я думал, было простой вещью.Рекурсивная функция, которая записывает вложенные элементы 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)

Моя ошибка:

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

Я никогда не понимал xquery, и не могу понять, почему это не такработает (это только у меня или в интернете поразительно мало ресурсов по XQuery?)

Ответы [ 2 ]

6 голосов
/ 12 марта 2010

Вы написали эту функцию процедурным образом, XQuery - это функциональный язык.

Каждое тело функции может быть только одним выражением; похоже, вы пытаетесь написать операторы (которых нет в XQuery).

Во-первых, за вашим выражением let должно следовать ключевое слово return.

return используется только как часть выражения FLWOR, функция всегда вычисляет значение. Как вы уже написали, return эквивалентно /return и поэтому вернет узел с именем return.

Строка $counter := $counter + 1 вообще не является допустимым XQuery. Вы можете установить переменную, подобную этой, только с выражением let, и в этом случае она создаст новую переменную с именем counter, которая заменит старую, которая будет находиться в области действия only в возвращаемом выражении переменная.

Правильный способ сделать то, что вы пытаетесь сделать, - это уменьшать значение аргумента $ каждый раз, когда функция повторяется, и останавливаться, когда вы нажимаете 0.

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

local:Test(3)

Обратите внимание, что я изменил название функции на Test. Название «PrintTest» вводило в заблуждение, поскольку это подразумевает, что функция что-то делает (а именно, печать). На самом деле функция просто возвращает узел, она не выполняет никакой печати. В чисто функциональном языке (который очень близок к XQuery) функция никогда не имеет побочных эффектов, она просто возвращает значение (или в данном случае узел).

1 голос
/ 12 мая 2012

Строка $counter := $counter + 1 действительна Сценарии XQuery .

...