Go Premium for a chance to win a PS4. Enter to Win

x
?
Solved

XSL: Counter

Posted on 2006-06-16
4
Medium Priority
?
1,091 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 1500 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

Concerto Cloud for Software Providers & ISVs

Can Concerto Cloud Services help you focus on evolving your application offerings, while delivering the best cloud experience to your customers? From DevOps to revenue models and customer support, the answer is yes!

Learn how Concerto can help you.

Question has a verified solution.

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

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…
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, …
This video shows how to quickly and easily deploy an email signature for all users in Office 365 and prevent it from being added to replies and forwards. (the resulting signature is applied on the server level in Exchange Online) The email signat…
Are you ready to place your question in front of subject-matter experts for more timely responses? With the release of Priority Question, Premium Members, Team Accounts and Qualified Experts can now identify the emergent level of their issue, signal…

876 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