`
Читать книги » Книги » Компьютеры и Интернет » Программирование » Алексей Валиков - Технология XSLT

Алексей Валиков - Технология XSLT

Перейти на страницу:

 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.

Цикл for

Частным случаем цикла 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 &lt; $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 &lt; $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">

   <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"/>

Перейти на страницу:

Откройте для себя мир чтения на siteknig.com - месте, где каждая книга оживает прямо в браузере. Здесь вас уже ждёт произведение Алексей Валиков - Технология XSLT, относящееся к жанру Программирование. Никаких регистраций, никаких преград - только вы и история, доступная в полном формате. Наш литературный портал создан для тех, кто любит комфорт: хотите читать с телефона - пожалуйста; предпочитаете ноутбук - идеально! Все книги открываются моментально и представлены полностью, без сокращений и скрытых страниц. Каталог жанров поможет вам быстро найти что-то по настроению: увлекательный роман, динамичное фэнтези, глубокую классику или лёгкое чтение перед сном. Мы ежедневно расширяем библиотеку, добавляя новые произведения, чтобы вам всегда было что открыть "на потом". Сегодня на siteknig.com доступно более 200000 книг - и каждая готова стать вашей новой любимой. Просто выбирайте, открывайте и наслаждайтесь чтением там, где вам удобно.

Комментарии (0)