Книга: Технология XSLT

Цикл while

Цикл while

Наиболее примитивной циклической конструкцией во многих языках программирования является цикл while (англ. пока). Цикл while, как правило, имеет следующий вид:

пока
 верно условие
выполнять
 действия

В качестве примера while-цикла напишем на языке Java программу вычисления факториала в итеративном стиле:

int factorial(int n) {
 int i = n;
 int result = 1;
 while (i != 0) {
  result = result * i;
  i--;
 }
 return result;
}

В этой функции условием является отличие значения переменной i от 0, а действиями — умножение значения переменной result на значение переменной i, и уменьшение значения этой переменной на 1.

Цикл while не может быть запрограммирован в XSLT итеративно потому как действия, как правило, изменяют значения переменных, в контексте которых вычисляется условие, определяющее, продолжать выполнение цикла или нет. Дадим другую общую запись цикла while, выделив изменение переменных:

пока
 верно условие(x1,x2, ...,xn)
выполнить
 x1' := функция1(x1,x2,...,xn)
 х2' := функция2(x1,x2,...,xn)
 ...
 xn' := функцияn(x1,x2,...,xn)
 действия(x1,x2,...,хn)
 x1 := x1'
 x2 := x2'
 ...
 xn := xn'
иначе
 вернуть результат(x1,...,хn)

Переопределение значений переменных x1, … , хn в этом случае выполняют n функций: функция1 …, функцияn. И если изменить значение переменной мы не могли, переопределить связанное с ней значение мы вполне в состоянии, добавив в контекст новый параметр или переменную с тем же именем.

Теперь мы можем записать весь цикл while как одну рекурсию:

while(x1, ..., xn) ::=
 если
  выполняется условие(x1, ..., xn)
 то
  действия(x1, ..., хn)
  while(функция1(x1, ..., хn),
   функция2(x1, ..., хn),
   ...,
   функцияn(x1, ..., xn))
 иначе
  результат(x1, ..., хn)

Теперь уже совершенно очевидно, как while-цикл должен выглядеть в преобразовании.

Листинг 11.10. Шаблон цикла while в общем виде

<xsl:template name="while">
 <xsl:param name="x1"/>
 <!-- ... -->
 <xsl:param name="xn"/>
 <xsl:choose>
  <xsl:when test="условие($x1,...,$xn)">
   <!-- Действия -->
   <xsl:call-template name="while">
    <xsl:with-param name="x1" select="функция_1($x1, ... $xn) "/>
    <!-- ... -->
    <xsl:with-param name="xn" select="функция_n($x1, ... $xn) "/>
   </xsl:call-template>
  </xsl:when>
  <xsl:otherwise>
   <xsl:value-of select="результат($x1, ..., $xn)"/>
  </xsl:otherwise>
 </xsl:choose>
</xsl:template>

В качестве примера приведем while-цикл для программы, вычисляющей факториал. Java-код был следующим:

while (i != 0) {
 result = result * i;
 i--;
}

В этом цикле участвуют две переменные — i и result. Функции, использующиеся в этом цикле, запишутся следующим образом:

условие($1, $result)      ::= ($i != 0)
функцияi($i, $result)     ::= ($i - 1)
функцияresult($i, $result) ::= ($i * $result)
результат($I, $result)    ::= ($result)

Именованный шаблон для этого случая будет иметь вид.

Листинг 11.11. Пример шаблона цикла while

<xsl:template name="while">
 <xsl:param name="i"/>
 <xsl:param name="result"/>
 <xsl:choose>
  <xsl:when test="$i != 0">
   <xsl:call-template name="while">
    <xsl:with-param name="i" select="$i — 1"/>
    <xsl:with-param name="result" select="$result * $i"/>
   </xsl:call-template>
  </xsl:when>
  <xsl:otherwise>
   <xsl:value-of select="$result"/>
  </xsl:otherwise>
 </xsl:choose>
</xsl:template>

Вызвать этот шаблон можно следующим образом:

<xsl:template match="/">
 <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.

Оглавление книги

Оглавление статьи/книги

Генерация: 0.036. Запросов К БД/Cache: 0 / 0
поделиться
Вверх Вниз