[xquery-talk] index-of() behavior

Joe Wicentowski joewiz at gmail.com
Thu Mar 19 15:05:08 PST 2009


An update: I actually used's Florent's function for one of my two
cases.  What I'm actually doing is processing footnotes (specifically,
TEI <note> elements) so they appear inline and at the end of the
document.  I'm using recursive typeswitching to mimic XSLT.  The "at"
clause worked for the 2nd case -- where I'm iterating through the
<notes> all at once, but it didn't work when in the 1st case, where
the function was only receiving one <note> at a time.  For that case,
I needed to step out of the received node and call Florent's
functions.

Thanks very much, Florent!

p.s. In case anyone's interested, here is the "at" clause at work:

declare function render:note-end($content, $options) as element() {
        <div class="footnotes">
            {
            for $note at $incr in $content//tei:note
            return
                if ($note/@type = 'summary') then
                    (: suppress ePub summary notes from being displayed :)
                    ()
                else
                    <p>
                        <a href="{concat('#fnref', $incr)}"
name="{concat('fn', $incr)}" title="Return to text">
                            <sup>
                                {data($note/@n)}
                            </sup>
                        </a>&#160;{render:recurse($note, $options)}
                    </p>
            }
        </div>
};

and here is where I call Florent's functions:

declare function render:note($node as element(tei:note), $options ) as
element() {
        let $incr :=
xs:integer(local:index-of($node/ancestor::tei:div[1]//tei:note,
$node))
        return
        <a href="{concat('#fn', $incr)}" name="{concat('fnref', $incr)}">
            <sup>
                {data($node/@n)}
            </sup>
            <span class="footnoteinline">
                {data($node/@n)}.&#160;{data($node)}
            </span>
        </a>
};


On Thu, Mar 19, 2009 at 11:55 AM, Florent Georges <lists at fgeorges.org> wrote:
>
> Joe Wicentowski wrote:
>
>> <results>{
>> let $content :=
>>     <x>
>>         <y n="1">z</y>
>>         <y n="2">z</y>
>>     </x>
>> for $child in $content/y
>> let $index := fn:index-of($content/y, $child)
>> return
>>     <result>{$index}</result>
>> }</results>
>
>> I expected this to return:
>
>> <results>
>>    <result>1</result>
>>    <result>2</result>
>> </results>
>
>  index-of() compares items by value.  If you want to use identity comparison instead, you can write your own function to do that.  A simple recursive function is obvious:
>
> declare function local:index-of($seq as node()*, $n as node())
>      as xs:integer*
> {
>   local:index-of($seq, $n, 1)
> };
>
> declare function local:index-of($seq as node()*, $n as node(), $i as xs:integer)
>      as xs:integer*
> {
>   if ( empty($seq) ) then
>      ()
>   else if ( $seq[1] is $n ) then
>      ( $i, local:index-of(remove($seq, 1), $n, $i + 1) )
>   else
>      local:index-of(remove($seq, 1), $n, $i + 1)
> };
>
> <results> {
>   let $content := <x>
>                      <y n="1">z</y>
>                      <y n="2">z</y>
>                   </x>
>   for $child in $content/y
>   return
>       <result>{ local:index-of($content/y, $child) }</result>
> }
> </results>
>
> results in:
>
> <results>
>   <result>1</result>
>   <result>2</result>
> </results>
>
>  Hope that helps,
>
> --
> Florent Georges
> http://www.fgeorges.org/
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>



More information about the talk mailing list