Solved

XSL: Counter

Posted on 2006-06-16
4
1,070 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 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

How Do You Stack Up Against Your Peers?

With today’s modern enterprise so dependent on digital infrastructures, the impact of major incidents has increased dramatically. Grab the report now to gain insight into how your organization ranks against your peers and learn best-in-class strategies to resolve incidents.

Question has a verified solution.

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

Suggested Solutions

Title # Comments Views Activity
XML filtering Windows Event Viewer 10 69
Convert Oracle data into XML document 2 75
Help with Syntax 9 51
Powershell XML in variable 4 34
The Problem How to write an Xquery that works like a SQL outer join, providing placeholders for absent data on the outer side?  I give a bit more background at the end. The situation expressed as relational data Let’s work through this.  I’ve …
The Confluence of Individual Knowledge and the Collective Intelligence At this writing (summer 2013) the term API (http://dictionary.reference.com/browse/API?s=t) has made its way into the popular lexicon of the English language.  A few years ago, …
Exchange organizations may use the Journaling Agent of the Transport Service to archive messages going through Exchange. However, if the Transport Service is integrated with some email content management application (such as an antispam), the admini…

756 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