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
Solved

XSL: Counter

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

Master Your Team's Linux and Cloud Stack

Come see why top tech companies like Mailchimp and Media Temple use Linux Academy to build their employee training programs.

Question has a verified solution.

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

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…
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…
Microsoft Active Directory, the widely used IT infrastructure, is known for its high risk of credential theft. The best way to test your Active Directory’s vulnerabilities to pass-the-ticket, pass-the-hash, privilege escalation, and malware attacks …
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…

860 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