This is an old thread but hopefully this would be useful for other
people in the future, seeing that when you google "XSLT counter", a
lot of other folks have this issue.

Recursion does work but is probably an over kill and you could blow your stack .
Another nice way to do counter is to make use of java.util.* classes.

Since Xalan can instantiate java classes, what you can do is declare
an java.util.ArrayList (or equivalent class) , and add an item to the
ArrayList on each iteration.  Then turn around and call the size()
method on the ArrayList.
Definitely not the best but it should solve most common counter problem.

Below is a sample Input file + sample XSLT and the equivalent output file

Sample Input File
=============
<Foo>
   <Bar>Line 1</Bar>
   <Bar>Line 2</Bar>
   <Bar>Line 3</Bar>
   <Bar>Line 4</Bar>
   <Bar>Line 5</Bar>
   <Bar>Line 6</Bar>
</Foo>

Sample XSLT
==========
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet
       xmlns:xsl='http://www.w3.org/1999/XSL/Transform'
       xmlns:xalan='http://xml.apache.org/xslt'
       xmlns:java="http://xml.apache.org/xslt/java";
       extension-element-prefixes="" exclude-result-prefixes="xsl xalan java"
       version="1.0">

   <!-- define the output parameters -->
   <xsl:output method='xml'  version='1.0' encoding='UTF-8'
     omit-xml-declaration='no' indent='yes' xalan:indent-amount='4' />

      <!-- Declare my counter variable here -->
   <xsl:variable name="javaCounter" select="java:java.util.ArrayList.new()"/>

   <xsl:template match="/Foo">
       <Foo>
           <xsl:for-each select="./Bar">
           <!-- increment the Counter , ie. add item to the ArrayList
object -->
           <xsl:variable name="Foo" select="java:add($javaCounter, '1')"/>
           <Bar><xsl:value-of select="."/></Bar>

           <!-- ask for the size of the ArrayList  -->
           <Counter><xsl:value-of select="java:size($myCounter)"/></Counter>
           </xsl:for-each>
       </Foo>
   </xsl:template>
</xsl:stylesheet>


Output File
=========
<?xml version="1.0" encoding="UTF-8"?>
<Foo>
   <Bar>Line 1</Bar><Counter>1</Counter>
   <Bar>Line 2</Bar><Counter>2</Counter>
   <Bar>Line 3</Bar><Counter>3</Counter>
   <Bar>Line 4</Bar><Counter>4</Counter>
   <Bar>Line 5</Bar><Counter>5</Counter>
   <Bar>Line 6</Bar><Counter>6</Counter>
</Foo>
------------------------------------------------------------------------------------



Subject:    RE: Counter in xsl with xalan
From:       "Steve Carton" <steve () chesbay ! net>
Date:       2006-02-08 15:54:03
Message-ID: 002c01c62cc7$e40b55e0$8664a8c0 () retrievalsystems ! com
[Download message RAW]

Use recursion, passing the current count to a named template and
incrementing it.

From: Mikael Petterson (KI/EAB) [mailto:[EMAIL PROTECTED] ]
Sent: Wednesday, February 08, 2006 10:27 AM
To: xalan-j-users@xml.apache.org
Subject: Counter in xsl with xalan



Hi,

Since there is no counter in xsl that is, where I can increment a number (
independent) of nodes.

I am using xalan to generate the following code:

new String [] {"eAgchCodes_name0", "eAgchCodes_name1",."eAgchCodes_name3"}

This is how the xml looks like:

<structMember name="eAgchCodes">
           <description>One to four codes.
           </description>
           <sequence>
               <long>
                   <range>
                       <min>0</min> <max>255</max>
                   </range>
               </long>
               <maxLength>4</maxLength>
           </sequence>
</structMember>

In order to generate the names I need a counter to increase each time until
all four strings have been generated.
Any ideas how I can do that with Xalan-Java? Extensions?

cheers,

Reply via email to