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)

Моя ошибка:

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

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


person Brian Hvarregaard    schedule 12.03.2010    source источник


Ответы (2)


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

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

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

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

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

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

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

local:Test(3)

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

person Oliver Hallam    schedule 12.03.2010
comment
Ура, надо заморочиться этим - person Brian Hvarregaard; 15.03.2010

Строка $counter := $counter + 1 допустима для XQuery Scripting.

person wcandillon    schedule 12.05.2012