xsl-list
[Top] [All Lists]

Re: xslt 2. index-of, nodes

2003-07-03 05:26:53
Dave,

I think that using the same method as you'd use in XSLT 1.0 would
work:

  count(preceding::loc[(_at_)hl = $context/@hl and
                       @side = $context/@side and
                       @pos = $context/@pos]) + 1

That does it, though I'm curious why your $context works, and
context-item() doesn't? Not the same as current()?

context-item() is long-hand for "." -- it gets you the context item,
not the current item (the distinction is the same as the distinction
between the context node and the current node in XSLT 1.0). If you
imagine what:

  count(preceding::loc[(_at_)hl = ./@hl and
                       @side = ./@side and
                       @pos = ./@pos]) + 1

would do, perhaps you can see why it doesn't work.

That's right. The arguments to index-of() are atomised to atomic
values, so you're getting the index of the <loc> element with the
same typed value as the <loc> element you're looking at.

So I can't find index-of (node-set, node) ? For this instance it
would have been useful.

Not using index-of() as it's currently defined. Of course you can
write your own function to get the indexes of a node in a sequence of
nodes:

<xsl:function name="my:index-of" as="xs:integer*">
  <xsl:param name="seq" as="node()*" />
  <xsl:param name="item" as="node()" />
  <xsl:for-each select="$seq">
    <xsl:if test=". is $item">
      <xsl:sequence select="position()" />
    </xsl:if>
  </xsl:for-each>
</xsl:function>

or use a for expression in an XPath:

  for $i in (1 to count($seq))
  return if ($seq[$i] is $item) then $i else ()

Of course there might be other, better, methods depending on how
you're processing the <loc> elements. For example, perhaps you
could use XSLT 2.0's grouping mechanism to process all the <loc>
elements in the group at once, and then just use position().

There are lots of loc elements with identical attribute values,
only the text content of the element changing. 

 O date1
   date2
   date3
is the sort of svg I want.

I'd still want the 'position' in the group, to calculate the Y
offset for the text, so its not an improvement...

Erm... my point was that if you were processing the group as a whole
then you could use the position() function to get you the position of
the <loc> within the group. Something like:

  <xsl:for-each-group select="loc" group-by="@hl">
    <xsl:for-each-group select="current-group()" group-by="@side">
      <xsl:for-each-group select="current-group()" group-by="@pos">
        <xsl:for-each select="current-group()">

          position in group: <xsl:value-of select="position()" />
        
        </xsl:for-each>
      </xsl:for-each-group>
    </xsl:for-each-group>
  </xsl:for-each-group>

(I can't believe that no one apart from me is bothered about having to
nest <xsl:for-each-group> as in the above when you want to group by
several things at once.)

Cheers,

Jeni

---
Jeni Tennison
http://www.jenitennison.com/


 XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list



<Prev in Thread] Current Thread [Next in Thread>