Solved

XSL: Counter

Posted on 2006-06-16
4
1,058 Views
Last Modified: 2008-02-01
Hi Gertone,
rather than using:

       <xsl:choose>
       <xsl:when test="position() mod 2 = 0">
...
       </xsl:when>
       <xsl:when test="position() mod 2 = 1">
...
       </xsl:when>       
       </xsl:choose>

...for color-changing line layout, I'll have to increment a local variable and then to test for...
I have a for-each loop and want to change line color from one to the other line, but cannot use above method since there may be some gaps in between (line 1, 5, 8, 10 etc.). So I' d like to use a variable.

Any way to do that:

i=1
i=i+1
MOD on i
0
Comment
Question by:go4java
  • 3
4 Comments
 
LVL 60

Expert Comment

by:Geert Bormans
ID: 16920785
Hi go4java,

the only way to do that is to use a recursive function
(through a named template)
you pass two parameters
- the variable you increment
- the next node in the series

I will post an example in a minute

Cheers!
0
 
LVL 60

Accepted Solution

by:
Geert Bormans earned 500 total points
ID: 16920981
go4java,

with this XML
<?xml version="1.0" encoding="UTF-8"?>
<list>
    <item>A</item>
    <item>B</item>
    <item>C</item>
    <item>C</item>
    <item>D</item>
</list>

and this XSLT
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    <xsl:template match="/">
        <html>
            <body>
                <table>
                    <xsl:call-template name="processItem">
                        <xsl:with-param name="node" select="//list/item[1]" />
                        <xsl:with-param name="counter" select="1"/>
                    </xsl:call-template>
                </table>
            </body>
        </html>
    </xsl:template>
    <xsl:template name="processItem">
        <xsl:param name="counter"/>
        <xsl:param name="node"/>
        <xsl:param name="bgrd">
            <xsl:choose>
                <xsl:when test="$counter mod 2 = 1">#aaaaaa</xsl:when>
                <xsl:otherwise>#333333</xsl:otherwise>
            </xsl:choose>
        </xsl:param>
        <tr bgcolor="{$bgrd}"><td><xsl:value-of select="$node"/></td></tr>
        <xsl:if test="$node/following-sibling::item">
            <xsl:choose>
                <xsl:when test="$node/text() = $node/following-sibling::item[1]/text()">
                    <xsl:call-template name="processItem">
                        <xsl:with-param name="node" select="$node/following-sibling::item[1]" />
                        <xsl:with-param name="counter" select="$counter"/>
                    </xsl:call-template>
                </xsl:when>
                <xsl:otherwise>
                    <xsl:call-template name="processItem">
                        <xsl:with-param name="node" select="$node/following-sibling::item[1]" />
                        <xsl:with-param name="counter" select="$counter + 1"/>
                    </xsl:call-template>
                </xsl:otherwise>
            </xsl:choose>
         </xsl:if>        
     </xsl:template>
</xsl:stylesheet>

you can see that the row color only switches when the values are not the same in to following lines
(just a stupid example to make my point)

the named template calls itself with the next item in the list
and an increased counter under a certain condition
(I assume that is what you need)

This is the only way because variables cannot change in XSLT
0
 
LVL 60

Expert Comment

by:Geert Bormans
ID: 16923691
go4java,

If you want to test on the position,
you can count the preceding siblings of item
This way you can eg. not switch colours on row 1, 5, 8 and 10

here is the XSLT, changed for that purpose
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    <xsl:template match="/">
        <html>
            <body>
                <table>
                    <xsl:call-template name="processItem">
                        <xsl:with-param name="node" select="//list/item[1]" />
                        <xsl:with-param name="counter" select="1"/>
                    </xsl:call-template>
                </table>
            </body>
        </html>
    </xsl:template>
    <xsl:template name="processItem">
        <xsl:param name="counter"/>
        <xsl:param name="node"/>
        <xsl:param name="bgrd">
            <xsl:choose>
                <xsl:when test="$counter mod 2 = 1">#abcdef</xsl:when>
                <xsl:otherwise>#efbcab</xsl:otherwise>
            </xsl:choose>
        </xsl:param>
        <tr bgcolor="{$bgrd}"><td><xsl:value-of select="$node"/></td></tr>
        <xsl:if test="$node/following-sibling::item">
            <xsl:variable name="poscnt" select="count($node/preceding-sibling::item) + 1"></xsl:variable>
            <xsl:choose>
                <xsl:when test="$poscnt = 1 or $poscnt = 5 or $poscnt = 8 or $poscnt = 10">
                    <xsl:call-template name="processItem">
                        <xsl:with-param name="node" select="$node/following-sibling::item[1]" />
                        <xsl:with-param name="counter" select="$counter"/>
                    </xsl:call-template>
                </xsl:when>
                <xsl:otherwise>
                    <xsl:call-template name="processItem">
                        <xsl:with-param name="node" select="$node/following-sibling::item[1]" />
                        <xsl:with-param name="counter" select="$counter + 1"/>
                    </xsl:call-template>
                </xsl:otherwise>
            </xsl:choose>
        </xsl:if>        
    </xsl:template>
</xsl:stylesheet>

you will need a bigger list to test this
<?xml version="1.0" encoding="UTF-8"?>
<list>
    <item>A</item>
    <item>B</item>
    <item>C</item>
    <item>D</item>
    <item>E</item>
    <item>F</item>
    <item>G</item>
    <item>H</item>
    <item>I</item>
    <item>J</item>
    <item>K</item>
    <item>L</item>
</list>

cheers

Geert
0
 

Author Comment

by:go4java
ID: 16932493
<xsl:stylesheet

version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"

xmlns:saxon="http://saxon.sf.net/"

extension-element-prefixes="saxon">

<!--************************************************************-->

<!--****SAXON initialization of variables***********************-->

<!--************************************************************-->

<xsl:variable name="pointer"

saxon:assignable="yes">0</xsl:variable>

+++

<saxon:assign name="pointer"><xsl:value-of select="$pointer +1"/>

</saxon:assign>




...just as completion and possible solution with Saxon extension...
0

Featured Post

3 Use Cases for Connected Systems

Our Dev teams are like yours. They’re continually cranking out code for new features/bugs fixes, testing, deploying, testing some more, responding to production monitoring events and more. It’s complex. So, we thought you’d like to see what’s working for us.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
AL3 Files 4 28
JQuery to parse xml string and get element by id 4 34
read an xml file in perl 2 30
XML SQL 8 25
The Client Need Led Us to RSS I recently had an investment company ask me how they might notify their constituents about their newsworthy publications.  Probably you would think "Facebook" or "Twitter" but this is an interesting client.  Their cons…
Browsing the questions asked to the Experts of this forum, you will be amazed to see how many times people are headaching about monster regular expressions (regex) to select that specific part of some HTML or XML file they want to extract. The examp…
This Micro Tutorial hows how you can integrate  Mac OSX to a Windows Active Directory Domain. Apple has made it easy to allow users to bind their macs to a windows domain with relative ease. The following video show how to bind OSX Mavericks to …
Although Jacob Bernoulli (1654-1705) has been credited as the creator of "Binomial Distribution Table", Gottfried Leibniz (1646-1716) did his dissertation on the subject in 1666; Leibniz you may recall is the co-inventor of "Calculus" and beat Isaac…

776 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question