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