Qualche barbatrucco con XSLT

Molti di voi sviluppando template su XSL si è scontrato più volte con le limitazioni di XSLT 1.0 specialmente sui loop. Cercando qua e la ho trovato dei suggerimenti interessanti per superare questi limiti.

Emulazione cicli for-loop

come sapete già, in XSLT non esiste un equivalente del ciclo for-loop come l’esempio in PHP:

for ($i = 0; $i < = 10; $i++) {
    echo 'loop '.$i;
}

Questo template riproduce bene il funzionamento di un loop incrementale usando un template ricorsivo con xsl:call-template:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
	<xsl:output method="html" indent="yes"/>
 
	<xsl:template match="/">
		<xsl:call-template name="for">
			<xsl:with-param name="i" select="number(1)"/>
		</xsl:call-template>
	</xsl:template>
 
	<!-- for loop function() emulation -->
	<xsl:template name="for">
		<xsl:param name="i">0</xsl:param>
		<xsl:choose>
		<xsl:when test="number($i) &lt;= 10">
                        loop '<xsl:value-of select="$i"/>' <br/>		
		        <xsl:call-template name="for">
			    <xsl:with-param name="i" select="$i + 1"/>
		       </xsl:call-template>
		</xsl:when>
		<xsl:otherwise/>
	</xsl:template>
</xsl:stylesheet>

che stamperà:
loop ‘1′
loop ‘2′

loop ‘10′

Ovviamente con qualche adattamento può essere usato per contesti diversi.

xsl:for-each in ordine inverso

Più di una volta si è avuta la necessita di ciclare una lista ricavata da una xpath in ordine inverso. Niente paura, la soluzione è di una semplicità immane:

<xsl:sort select="position()" data-type="number" order="descending"/>

da mettere dentro il nodo xsl:for-each come nel seguente esempio:

<xsl:template match="book">
	<xsl:for-each select="part">
		<xsl:sort select="position()" data-type="number" order="descending"/>
		<xsl:value-of select="title"/>
		<br/>
	</xsl:for-each>
</xsl:template>

Leave a Reply