[xquery-talk] problem with loops

Titash Neogi titash_neogi at symantec.com
Wed Jan 4 02:12:47 PST 2006

Thanks for the replies.

Here is a simplified outline of what I am trying to do

I have a xml file as shown below

<pre> DATA0 </pre> <res> DATA1 </res> </map>
<pre> DATA1 </pre> <res> DATA2 </res> </map>
<pre> DATA2 </pre> <res> DATA3 </res> </map>
<pre> DATA3 </pre> <res> DATA4 </res> </map>


Now the idea is that if I search for DATA4, the system will trace its
path backwards and find out all the linked dependencies. So the output
would something like

Query - DATA4


The algorithm I am trying to implement is

1. Obtain input from user

2. repeat steps 3 through 5 for the entire file 

3. send user input to function A that identifies the <map> </map> chunk
corresponding to this input

4. send the output of function A (step 3) to a function B that extracts
the pre/text() bit of this chunk

5. send the output of function B (step 4) to function A (step 3 again)
to identify the <map> </map> chunk

Now, to repeat, my problem is that my function overwrites the values in
the loop so that I only get the last variable's output.

Hope this makes the logic a little clearer.

Any further help on this would be really nice.


-----Original Message-----
From: Michael Kay [mailto:mhk at mhk.me.uk] 
Sent: Wednesday, January 04, 2006 3:19 PM
To: Titash Neogi; talk at xquery.com
Subject: RE: [xquery-talk] problem with loops

> Something as shown below
> ____________________________________
> declare function lcl:caller()
> { 
>        let $QV1 := request:request-parameter("val1","")
>        let $count:= 0
>        let $QV1:= lcl:tracer($QV1)
> for $d in /maps/map
>        let $k:= lcl:rend($QV1)
>        let $QV2:= $QV1
>        let $QV1:= lcl:tracer($k)
>        return $QV2
> };
> ________________________________________

I don't know what your various functions here are doing, but the general
approach to this kind of problem in a functional language is to use
recursion. Your loop here is a bit odd because it doesn't depend on $d,
you seem to be using /maps/map merely to determine how many iterations
should be. This suggests a recursive solution along these lines:

declare function f:doit (
    $QV1 as item()*
    $count as xs:integer ) as item()* {
  if ($count eq 0)
  then $QV1
  else f:doit(lcl:tracer(lcl:rend($QV1), $count - 1))

I don't think that's precisely the logic, but it's difficult to reverse
engineer your algorithm from incorrect code.

Michael Kay

More information about the talk mailing list