position()

Maybe I’m doing something terribly wrong, but I can’t get position() to work. In the following query, the function always delivers “1”, even if $a contains multiple “track” child elements. BTW, position() does work in a filter expression such as $a/track[position()=2], but it fails when used in the body of a FOR loop.

DEFAULT ELEMENT NAMESPACE=“404


{FOR $a IN collection(“encyclopedia”)/album
RETURN







{ FOR $c IN $a/coverImage
RETURN

}



{string($a/title)}



{ FOR $p IN $a/publisher
RETURN
concat(“Publisher: “,string($p))
}
AlbumNo: {string($a/@albumNo)}

{string($a/title)}



Tracks



{ FOR $t IN $a/track
RETURN




}

{ concat(string($t/position()),”-”,string($t/title)) }

{ concat(substring-before(substring-after(string($t/duration),“M”),“S”),“:”,substring-after(string($t/duration),“S”)) }


}


Berthold Daum

Hi Berthold,

Maybe this is what’s happening:

The for loop iterates through each track, and assigns the value to a variable ($t). Therefore the variable will contain only one track at a time, and therefore, its position will always be 1.

Perhaps a workaround could be:

LET $numTracks = count($a/track)
FOR $t IN (1 TO $numTracks)
LET $track = $a/track[$t]
RETURN


{ concat(string($t),“-”,string($track/title)) }


{ concat(substring-before(substring-after(string($track/duration),“M”),“S”),“:”,substring-after(string($track/duration),“S”)) }


}

Best Regards,
Puny Sen

Hi Puny,

this worked, indeed.

Obviously, to FOR loop seems to create a new context consisting only of the track element selected for one iteration. Not very intuitive though, one should rather expect the whole album/track node list as the context. The Working Draft, hoever, is not very specific about context in loops.

Many thanks,

Berthold.

Berthold Daum

I’m afraid this one is going to catch a lot of people out: the dynamic context (context item, position, and size) are not changed within a FLWR expression. If you want to use the position, you have to turn it around as:

for $i in 1 to count($sequence)
let $x := $sequence[$i]

and then you can refer to the position as $i.

Michael Kay