tags:

views:

148

answers:

1

Hi all, Im new on this project and am going to write, what i thought was a simple thing. A recursive function that writes nested xml elements in x levels (denoted by a variable). So far I have come up with this, but keeps getting a compile error. Please note that i have to generate new xml , not query existing 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)

My error is:

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

I never understood xquery, and cant quite see why this is not working (is it just me or are there amazingly few resources on the Internet concerning XQuery?)

A: 

You have written this function in a procedural manner, XQuery is a functional language.

Each function body can only be a single expression; it looks like you are trying to write statements (which do not exist in XQuery).

Firstly, your let expression must be followed by a return keyword.

return is only used as part of a flowr expression, a function always evaluates to a value. As you have written it return is equivalent to /return and so will return a node called return.

The line counter := counter + 1 is not valid XQuery at all. You can only set a variable like this with a let expression, and in this case it would create a new variable called counter which replaced the old one, that would be in scope only in the return expression of the variable.

The correct way to do what you are trying to do is to reduce the value of $argument each time the function recurses, and stop when you hit 0.

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

local:Test(3)

Note that I have changed the name of the function to Test. The name "PrintTest" was misleading, as this implies that the function does something (namely, printing). The function in fact just returns a node, it does not do any printing. In a purely functional langauge (which XQuery is quite close to) a function never has any side effects, it merely returns a value (or in this case a node).

Oliver Hallam
Cheers, have to get my head wrapped around this
H4mm3rHead