Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

XSLT : Looping from 1 to 60

Tags:

xslt

What is the best way to loop in XSLT from 1 to 60? I research in net, there are some templates to do this, is there any other way for example like a built-in function?

like image 960
Ianthe Avatar asked Jan 31 '12 08:01

Ianthe


People also ask

How to make a loop in XSLT?

You create an XSLT loop with the <xsl:for-each> tag. The value of the select attribute in this tag is an XPath expression that allows you to specify the data element to loop through. XPath expressions are constructed like file paths in an operating system, the forward slash (/) selects subdirectories.

How do you iterate through an array in XSLT?

Anyway, for a start, I would suggest to use <xsl:variable name="listData" select="met:getData($Id)"/> , that is all you can do on the XSLT side to bind the variable to the result from the function call, your current attempt makes the variable hold a tree fragment containing a text node with the string value of the ...

Is XSLT 2.0 backward compatibility?

The XSLT 2.0 engine is backwards compatible. The only time the backwards compatibility of the XSLT 2.0 engine comes into effect is when using the XSLT 2.0 engine to process an XSLT 1.0 stylesheet.

Can XSLT transform XML to CSV?

This post shows you how to convert a simple XML file to CSV using XSLT. The following XSL Style Sheet (compatible with XSLT 1.0) can be used to transform the XML into CSV. It is quite generic and can easily be configured to handle different xml elements by changing the list of fields defined ar the beginning.


2 Answers

In XSLT 2.0,

<xsl:for-each select="1 to 60">...</xsl:for-each> 

But I guess that you must be using XSLT 1.0, otherwise you wouldn't be asking.

In XSLT 1.0 you should use recursion: a template that calls itself with a counter that's incremented on each call, and the recursion terminates when the required value is reached.

Alternatively there's a workaround in XSLT 1.0: provided your source document contains at least 60 nodes, you can do

<xsl:for-each select="(//node())[60 >= position()]">...</xsl:for-each> 
like image 115
Michael Kay Avatar answered Sep 21 '22 11:09

Michael Kay


The problem with simple recursion when processing long sequences is that often the space for the call stack becomes insufficient and the processing ends due to stack overflow. This typically happens with sequence length >= 1000.

A general technique to avoid this (implementable with any XSLT processor, even if it doesn't recognize tail-recursion) is DVC (Divide and Conquer) style recursion.

Here is an example of a transformation that successfully prints the numbers from 1 to 1000000 (1M):

<xsl:stylesheet version="1.0"      xmlns:xsl="http://www.w3.org/1999/XSL/Transform">      <xsl:output method="text"/>       <xsl:template match="/">       <xsl:call-template name="displayNumbers">         <xsl:with-param name="pStart" select="1"/>         <xsl:with-param name="pEnd" select="1000000"/>       </xsl:call-template>      </xsl:template>       <xsl:template name="displayNumbers">       <xsl:param name="pStart"/>       <xsl:param name="pEnd"/>        <xsl:if test="not($pStart > $pEnd)">        <xsl:choose>         <xsl:when test="$pStart = $pEnd">           <xsl:value-of select="$pStart"/>           <xsl:text>&#xA;</xsl:text>         </xsl:when>         <xsl:otherwise>           <xsl:variable name="vMid" select=            "floor(($pStart + $pEnd) div 2)"/>           <xsl:call-template name="displayNumbers">            <xsl:with-param name="pStart" select="$pStart"/>            <xsl:with-param name="pEnd" select="$vMid"/>           </xsl:call-template>           <xsl:call-template name="displayNumbers">            <xsl:with-param name="pStart" select="$vMid+1"/>            <xsl:with-param name="pEnd" select="$pEnd"/>           </xsl:call-template>         </xsl:otherwise>        </xsl:choose>       </xsl:if>      </xsl:template> </xsl:stylesheet> 

When applied on any XML document (not used) this transformation produces the wanted result -- all the numbers from 1 to 1000000.

You can use/adapt this transformation for any task that needs to "do something N times".

like image 45
Dimitre Novatchev Avatar answered Sep 19 '22 11:09

Dimitre Novatchev