Arial Century Courier Georgia Tahoma Verdana Times New Roman
-
+
<xsl:call-template name="while">
<xsl:with-param name="i" select="6"/>
<xsl:with-param name="result" select="1"/>
</xsl:call-template>
</xsl:template>
Результатом будет, естественно, число
720
.
Частным случаем цикла
while
является цикл
for
. В разных языках программирования
for
имеет различную семантику; мы будем рассматривать циклы
for
вида
for (int i = 0; i < n; i++) { ... }
в языках Java и С или
for i := 0 to n-1 do begin ... end;
в Pascal. Иными словами, нас будет интересовать циклическое выполнение определенных действий при изменении значения некоторой переменной (называемой иногда индексом цикла) в интервале целых чисел от 0 до n включительно.
Цикл
for
может быть определен через
while
с использованием следующих условных и изменяющих функций:
условие ($i, $n,$x1,...,$хk) :: = ($i < $n)
функция i ($i, $n, $x1, ... , $xk) ::= ($i + 1)
функция n ($i, $n, $x1, ..., $xk) :: = ($n)
Шаблон цикла
for
в общем виде будет выглядеть как.
Листинг 11.12. Шаблон цикла for в общем виде
<xsl:template name="for">
<xsl:param name="i" select="0"/>
<xsl:param name="n"/>
<!-- Другие переменные -->
<xsl:param name="x1"/>
<!-- ... – ->
<xsl:param name="xk"/>
<xsl:choose>
<xsl:when test="$i < $n">
<!-- Действия -->
<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 функция 1 ($i, $n, $x1, ..., $xk) "/>
<!-- ... – ->
<xsl:with-param name="xk" select="функция k ($i, $n, $x1, ..., $xk)"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="результат ($i,$n,$x1,...,$xk)"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
В качестве примера цикла
for
приведем шаблон, вычисляющий
n
первых чисел Фибоначчи.
Числа Фибоначчи — это рекуррентная последовательность вида
1 1 2 3 5 8 13 21 ...
и так далее, где каждое последующее число определяется как сумма двух предыдущих.
Для вычисления
n
первых чисел Фибоначчи мы можем использовать две переменные
current
и
last
, соответствующих текущему число и числу, полученному на предыдущем шаге соответственно. Функции, переопределяющие эти переменные, совершенно очевидны:
функция last ($i, $n, $last, $current) ::= ($current)
функция current ($i, $n, $last, $current) ::= ($current + $last)
Поскольку в данном случае нам не нужно возвращать результат, нужно лишь циклически выводить очередное число Фибоначчи, шаблон
for
может быть немного упрощен использованием элемента
xsl:if
вместо
xsl:choose
.
Листинг 11.13. Шаблон, вычисляющий числа Фибоначчи
<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
выводится заданное число раз.
Листинг 11.14. Вывод 10 элементов option
<xsl:stylesheet
version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform'">
<xsl:template match="/">
<xsl:call-template name="for">