Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

how to keep a running count without variable reassigment

302 views
Skip to first unread message

Buma

unread,
Jul 27, 2005, 12:46:24 PM7/27/05
to
the inability of variable reassignment to keep a running count in xsl
is giving me fits,
can someone take the following xml:

<columns>
<column>
<col>apple</col>
<col>orange</col>
<col>banana</col>
</column>
<column>
<col>car</col>
<col>train</col>
<col>boat</col>
</column>
<column>
<col>a</col>
<col>b</col>
<col>c</col>
</column>
</columns>
and produce the following output ?

1 apple car a
2 apple car b
3 apple car c
4 apple train a
5 apple train b
6 apple train c
7 apple boat a
8 apple boat b
9 apple boat c
10 orange car a
11 orange car b
12 orange car c
13 orange train a
14 orange train b
15 orange train c
16 orange boat a
17 orange boat b
18 orange boat c
19 banana car a
20 banana car b
21 banana car c
22 banana train a
23 banana train b
24 banana train c
25 banana boat a
26 banana boat b
27 banana boat c

obviously, the biggest problem is outputting the row number

Dimitre Novatchev

unread,
Jul 27, 2005, 4:06:15 PM7/27/05
to

"Buma" <dev...@gmail.com> wrote in message
news:1122482784.6...@o13g2000cwo.googlegroups.com...

It is quite simple, if the transformation is performed in two passes with
the results being numbered in the second pass.

Below is a one-pass solution:

This transformation:

<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msxsl="urn:schemas-microsoft-com:xslt"
exclude-result-prefixes="xsl msxsl"
>
<xsl:output omit-xml-declaration="yes"/>

<xsl:variable name="vrtfnextCombinations">
<xsl:for-each select="*/*">
<n>
<xsl:call-template name="numCombinations">
<xsl:with-param name="pCurGroup" select="."/>
</xsl:call-template>
<xsl:text>&#xA;</xsl:text>
</n>
</xsl:for-each>
</xsl:variable>

<xsl:variable name="vnextCombinations"
select="msxsl:node-set($vrtfnextCombinations)/*"/>

<xsl:template match="/">
<xsl:call-template name="combineSiblings">
<xsl:with-param name="pCurGroup" select="*/*[1]"/>
</xsl:call-template>
</xsl:template>

<xsl:template name="combineSiblings">
<xsl:param name="pCurGroup" select="/.."/>
<xsl:param name="pCurCombination"/>
<xsl:param name="pNum" select="1"/>

<xsl:choose>
<xsl:when test="$pCurGroup">
<xsl:for-each select="$pCurGroup/*">
<xsl:variable name="vcurPos" select="position()"/>
<xsl:call-template name="combineSiblings">
<xsl:with-param name="pCurGroup"
select="$pCurGroup/following-sibling::*[1]"/>
<xsl:with-param name="pCurCombination"
select="concat($pCurCombination, ., ' ')"/>
<xsl:with-param name="pNum"
select="$pNum
+
$vnextCombinations[count($pCurGroup/preceding-sibling::*)+1]
*
($vcurPos - 1)
"/>
</xsl:call-template>
</xsl:for-each>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="concat($pNum, ' ', $pCurCombination)"/>
<xsl:text>&#xA;</xsl:text>
</xsl:otherwise>
</xsl:choose>

</xsl:template>

<xsl:template name="numCombinations">
<xsl:param name="pCurGroup" select="/.."/>

<xsl:choose>
<xsl:when test="not($pCurGroup/following-sibling::*[1])">1</xsl:when>
<xsl:otherwise>
<xsl:variable name="vNextCombinations">
<xsl:call-template name="numCombinations">
<xsl:with-param name="pCurGroup"
select="$pCurGroup/following-sibling::*[1]"/>
</xsl:call-template>
</xsl:variable>

<xsl:value-of select="count($pCurGroup/*) * $vNextCombinations"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>

when performed against this (your) xml document:

<columns>
<column>
<col>apple</col>
<col>orange</col>
<col>banana</col>
</column>
<column>
<col>car</col>
<col>train</col>
<col>boat</col>
</column>
<column>
<col>a</col>
<col>b</col>
<col>c</col>
</column>
</columns>

produces the wanted result:

Needless to say, the transformation above could be much simpler, had I used
FXSL.

Hope this helped.

Cheers,
Dimitre Novatchev


Buma

unread,
Jul 28, 2005, 9:42:05 PM7/28/05
to
you are a genius
thanks!!

Message has been deleted

Dimitre Novatchev

unread,
Jul 30, 2005, 1:17:29 AM7/30/05
to
In principle, yes -- combine the set of teams with itself.

Only look out to exclude any match of a team against itself.

I will be able to send something more specific in two weeks time.


Cheers,
Dimitre Novatchev

<Gad...@gmail.com> wrote in message
news:1122607943.7...@g47g2000cwa.googlegroups.com...
> whoa! that's slick.
>
> Dimitre, will a similar XSLT allow me to make schedules for sports
> teams ? (Team 1 vs Team 2, etc) I've been trying to figure out how to
> do this and only produce combos that haven't been used before, eg Team
> 1 vs Team 3 the following week, etc.
>


0 new messages