I'm curious if there is a more elegant way to use a sequence
expression to process two adjacent elements at a time. With
XSLT 1.0 I would have used recursion, but with XSLT/XPath 2.0
I'm wondering if I can exploit sequences. Below is something
I've come up with so far.
<xsl:for-each select="for $i in 1 to (count(*) idiv 2 +
(count(*) mod 2)) return *[($i*2)-1]">
<pair>
<xsl:copy-of select="." />
<xsl:copy-of select="./following-sibling::*[1]" />
</pair>
</xsl:for-each>
It seems to me that you can either write code that assumes you're working
with a sequence of siblings, or you can write code that works with an
arbitrary sequence. For sibling elements, the following works just fine:
<xsl:for-each select="*[position() mod 2 = 1]">
<pair>
<xsl:copy-of select="., following-sibling::*[1]" />
</pair>
</xsl:for-each>
If you want to work with an arbitrary sequence $SEQ (not necessarily
siblings), try
<xsl:for-each select="1 to count($SEQ)[. mod 2 = 1]">
<xsl:variable name="p" select="."/>
<pair>
<xsl:copy-of select="$SEQ[$p], $SEQ[$p+1]" />
</pair>
</xsl:for-each>
Alternatively of course there is
<xsl:for-each-group select="$SEQ" group-adjacent="(position()-1) idiv 2">
<pair>
<xsl:copy-of select="current-group()"/>
</pair>
</xsl:for-each-group>
An interesting side note, I thought the sequence expression
would error because of divide by zero, but it appears to be
side effect free, at least with Saxon.
I can't see where you think you might be dividing by zero.
Michael Kay
http://www.saxonica.com/
--~------------------------------------------------------------------
XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list
To unsubscribe, go to: http://lists.mulberrytech.com/xsl-list/
or e-mail: <mailto:xsl-list-unsubscribe(_at_)lists(_dot_)mulberrytech(_dot_)com>
--~--