<!-- Действия -->
<xsl:call-template name='for'>
<xsl:with-param name='i' select='$i + 1'/>
<xsl:with-param name='n' select='$n'/>
<!-- Другие переменные -->
<xsl:with-param' name='x1' select
<!-- ... -->
<xsl:with-param name='xk' select='
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select='
</xsl:otherwise>
</xsl:choose>
</xsl:template>
В качестве примера цикла for
приведем шаблон, вычисляющий n
первых чисел Фибоначчи.
Числа Фибоначчи — это рекуррентная последовательность вида
1 1 2 3 5 8 13 21 ...
и так далее, где каждое последующее число определяется как сумма двух предыдущих.
Для вычисления n
первых чисел Фибоначчи мы можем использовать две переменные current
и last
, соответствующих текущему число и числу, полученному на предыдущем шаге соответственно. Функции, переопределяющие эти переменные, совершенно очевидны:
Поскольку в данном случае нам не нужно возвращать результат, нужно лишь циклически выводить очередное число Фибоначчи, шаблон for
может быть немного упрощен использованием элемента xsl:if
вместо xsl:choose
.
<xsl:template name='for'>
<xsl:param name='i' select='0'/>
<xsl:param name='n'/>
<xsl:param name='last' select='0'/>
<xsl:param name='current' select='1'/>
<xsl:if test='$i < $n'>
<xsl:text> </xsl:text>
<xsl:value-of select='$current'/>
<xsl:call-template name='for'>
<xsl:with-param name='i' select='$i + 1'/>
<xsl:with-param name='n' select='$n'/>
<xsl:with-param name='last' select='$current'/>
<xsl:with-param name='current' select='$last + $current'/>
</xsl:call-template>
</xsl:if>
/xsl:template>
Вызванный в основном шаблоне как:
<xsl:template match='/'>
<xsl:call-template name='for'>
<xsl:with-param name='n' select='6'/>
</xsl:call-template>
</xsl:template>
этот шаблон создаст в выходящем документе последовательность:
1 1 2 3 5 8
Приведем еще более простой пример, в котором элемент option
выводится заданное число раз.
<xsl:stylesheet
version='1.0'
xmlns:xsl='http://www.w3.org/1999/XSL/Transform''>
<xsl:template match='/'>
<xsl:call-template name='for'>
<xsl:with-param name='n' select='10'/>
</xsl:call-template>
</xsl:template>
<xsl:template name='for'>
<xsl:param name='i' select='0'/>
<xsl:param name='n'/>
<xsl:if test='$i < $n'>
<option>
<xsl:value-of select='$i'/>
</option>
<xsl:call-template name='for'>
<xsl:with-param name='i' select='$i + 1'/>
<xsl:with-param name='n' select='$n'/>
</xsl:call-template>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
<option>0</option>
<option>1</option>
<option>2</option>
<option>3</option>
<option>4</option>
<option>5</option>
<option>6</option>
<option>7</option>
<option>8</option>
<option>9</option>
Пожалуй, этим примером мы и закончим рассмотрение рекурсии. Осталось лишь добавить, что при