Solved

XSL: Counter

Posted on 2006-06-16
4
1,039 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

Top 6 Sources for Identifying Threat Actor TTPs

Understanding your enemy is essential. These six sources will help you identify the most popular threat actor tactics, techniques, and procedures (TTPs).

Join & Write a Comment

Suggested Solutions

Title # Comments Views Activity
illegal characters in XML using UTF-8 8 32
Detect file exist or not 3 81
microsoft access - xml 10 26
XML & .net 5 20
Introduction In my previous article (http://www.experts-exchange.com/Microsoft/Development/MS-SQL-Server/SSIS/A_9150-Loading-XML-Using-SSIS.html) I showed you how the XML Source component can be used to load XML files into a SQL Server database, us…
Many times as a report developer I've been asked to display normalized data such as three rows with values Jack, Joe, and Bob as a single comma-separated string such as 'Jack, Joe, Bob', and vice versa.  Here's how to do it. 
This video gives you a great overview about bandwidth monitoring with SNMP and WMI with our network monitoring solution PRTG Network Monitor (https://www.paessler.com/prtg). If you're looking for how to monitor bandwidth using netflow or packet s…
In this tutorial you'll learn about bandwidth monitoring with flows and packet sniffing with our network monitoring solution PRTG Network Monitor (https://www.paessler.com/prtg). If you're interested in additional methods for monitoring bandwidt…

759 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

Need Help in Real-Time?

Connect with top rated Experts

21 Experts available now in Live!

Get 1:1 Help Now