[xsl] XSLT recursion problem

Subject: [xsl] XSLT recursion problem
From: Paolo Vaccari <vaccari@xxxxxxxxxxxx>
Date: Fri, 23 Sep 2005 13:44:42 +0200
Hi all,
I'm trying to write an extension for an xml language that doesn't have 
a "loop" or "repeat" statement. Thus I have to write some XSLT code 
to expand my own <repeat> element.
At the moment my best solution is the following.

For XML:
<ax:repeat xmlns:ax="...">
  <sometag>
    <ax:items element="txt">
      <ax:item src="txt1.txt"/>
      <ax:item src="txt2.txt"/>
    </ax:items>
    <ax:items element="img">
      <ax:item src="img1.jpg"/>
      <ax:item src="img2.jpg"/>
    </ax:items>
  </sometag>
</ax:repeat>

The output I want is:
<sometag>
  <txt src="txt1.txt"/>
  <img src="img1.jpg"/>
</sometag>
<sometag>
  <txt src="txt2.txt"/>
  <img src="img2.jpg"/>
</sometag>

The XSLT to get this output is:
<xsl:stylesheet version="1.0" 
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform"; 
                xmlns:ax="...">

  <!-- apply templates for ax:repeat -->
  <xsl:template match="ax:repeat">
    <!-- the <item> to be processed at each loop-->
    <xsl:param name="index" select="1"/>
    <!-- process <items> and <sometag>, passing $index -->
    <xsl:apply-templates>
      <xsl:with-param name="index" select="$index"/>
    </xsl:apply-templates>
    <!-- check if other loops are needed -->
    <xsl:if test="$index &lt; 
count(descendant-or-self::ax:items[1]/ax:item)">
      <!-- continue recursively -->
      <xsl:apply-templates select="self::ax:repeat">
        <xsl:with-param name="index" select="$index + 1"/>
      </xsl:apply-templates>
    </xsl:if>
  </xsl:template>

  <!-- apply templates for ax:items -->
  <xsl:template match="ax:items">
    <xsl:param name="index"/>
    <xsl:element name="{@element}">
      <!-- element content -->
    </xsl:element>
  </xsl:template>

Ok, I have what I want, so what's the problem?
To get this, I have to propagate the $index parameter through the 
<sometag>, this way:

<xsl:template match="sometag">
  <xsl:param name="index" select="1"/>
  <sometag>
    <xsl:apply-templates>
      <xsl:with-param name="index" select="$index"/>
    </xsl:apply-templates>
    <!-- sometag content -->
  </sometag>
</xsl:template>

This is very bad, because I have to modify the <sometag> template, 
which has nothing to do with my extension.
Anyone has a better idea?
Thanks
Paolo Vaccari

Current Thread