Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

XSLT How to do a classic for x to y loop?

Tags:

xslt

xslt-1.0

I need to do a classic for i=0 to N loop, how can it be done in xstl 1.0?

thanks.

<xsl:for-each select="¿¿¿$i=0..5???">
    <fo:block>
        <xsl:value-of select="$i"/>
    </fo:block>
</xsl:for-each>

To give an example, I have

<foo>
    <bar>Hey!</bar>
</foo>

And want an output of

Hey!
Hey!
like image 994
jpaoletti Avatar asked Oct 21 '25 13:10

jpaoletti


1 Answers

XSLT is a functional programming language and as such it is very different to any procedural languages you already know.

Although for loops are possible in XSLT, they do not make use of the inherent strengths of XSLT (and functional programming in general).

for loops are routinely misused to address problems that are best solved with a functional approach instead (that is, matching templates). In other words, a loop is not really a "classic" in XSLT.

So, you might have to double back, identify the problem you are facing instead of discussion your solution. Then, the XSLT community might be able to suggest a solution that is more functional in nature. It might be that you've fallen victim to the XY problem.


Now, among the things XSLT is inherently good at is recursion. Often, problems that are solved with loops in procedural languages are solved with recursive templates in XSLT.

<xsl:template name="recursive-template">
   <xsl:param name="var" select="5"/>
   <xsl:choose>
     <xsl:when test="$var > 0">
       <xsl:value-of select="$var"/>
       <xsl:call-template name="recursive-template">
         <xsl:with-param name="var" select="$var - 1"/>
       </xsl:call-template>
     </xsl:when>
     <xsl:otherwise/>
   </xsl:choose>
</xsl:template>

To summarize, I suggest you look at "classic" recursion instead of "classic" for loops. You find more information about exactly this topic in an IBM article here.


EDIT as a response to your edited question. If your problem really boils down to outputting text content twice:

<?xml version="1.0" encoding="utf-8"?>

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

   <xsl:output method="text"/>

   <xsl:template match="/foo">
      <xsl:apply-templates select="bar"/>
      <xsl:apply-templates select="bar"/>
   </xsl:template>

</xsl:stylesheet>

This is not feasible of course for a dynamic number of iterations.

like image 55
Mathias Müller Avatar answered Oct 23 '25 06:10

Mathias Müller