Subject: RE: two at a time, using a sequence expression
From: "John Cavalieri" <john.cavalieri@xxxxxxxxx>
Date: Fri, 6 Jun 2008 11:15:09 -0500
|
Hi Martin, Michael,
Thanks for the suggestions. I knew my attempt looked clunky.
Michael, you are right, there is no divide by zero in my example. I
was mixed up with a zero count divided by 2 (flip flopped in my head),
which of course isn't an issue.
-John
> Date: Thu, 05 Jun 2008 18:33:26 +0200
> To: xsl-list@xxxxxxxxxxxxxxxxxxxxxx
> From: Martin Honnen <Martin.Honnen@xxxxxx>
> Subject: Re: two at a time, using a sequence expression
> Message-ID: <48481556.9080209@xxxxxx>
>
> John Cavalieri wrote:
>
> > <xsl:template match="/pairs">
> > <xsl:copy>
> > <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>
> > </xsl:copy>
> > </xsl:template>
>
> Doesn't the following suffice to achieve the same result?
>
> <xsl:template match="/pairs">
> <xsl:copy>
> <xsl:for-each select="*[position() mod 2 = 1]">
> <pair>
> <xsl:copy-of select="."/>
> <xsl:copy-of select="following-sibling::*[1]"/>
> </pair>
> </xsl:for-each>
> </xsl:copy>
> </xsl:template>
>
> --
>
> Martin Honnen
> http://JavaScript.FAQTs.com/
>
> ------------------------------
>
> Date: Thu, 5 Jun 2008 22:58:18 +0100
> To: <xsl-list@xxxxxxxxxxxxxxxxxxxxxx>
> From: "Michael Kay" <mike@xxxxxxxxxxxx>
> Subject: RE: two at a time, using a sequence expression
> Message-ID: <62425D6AAB9D46168585B9F310563558@Sealion>
>
> > 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/
>
> ------------------------------
--
John Cavalieri
john.cavalieri@xxxxxxxxx
|