`

Стивен Холзнер - XSLT

1 ... 78 79 80 81 82 ... 115 ВПЕРЕД
Перейти на страницу:

     <xsl:call-template name="localize">

      <xsl:with-param name="language" select="'fr'"/>

     </xsl:call-template>

    </H1>

    <TABLE BORDER="2">

     <TR>

      <TD>Name</TD>

      <TD>Mass</TD>

      <TD>Radius</TD>

      <TD>Day</TD>

     </TR>

     <xsl:apply-templates/>

    </TABLE>

   </BODY>

  </HTML>

 </xsl:template>

 <xsl:template name="localize">

  <xsl:param name="language"/>

  <xsl:if test="$language='en'">

   <xsl:text>Planets</xsl:text>

  </xsl:if>

  <xsl:if test="$language='de'">

   <xsl:text>Planeten</xsl:text>

  </xsl:if>

  <xsl:if test="$language='fr'">

   <xsl:text>Plan&#232;tes</xsl:text>

  </xsl:if>

 </xsl:template>

 .

 .

 .

Вот результирующий локализованный документ:

<HTML>

 <HEAD>

  <TITLE>Plan&egrave;tes</TITLE>

 </HEAD>

 <BODY>

  <H1>Plan&egrave;tes</H1>

  <TABLE BORDER="2">

   <TR>

    <TD>Name</TD>

    <TD>Mass</TD>

    <TD>Radius</TD>

    <TD>Day</TD>

   </TR>

   .

   .

   .

Этот документ показан на рис. 9.3.

Рис. 9.3. Вызов именованного шаблона с параметрами для установки языков

Вызов шаблона во многом похож на вызов функции, что обсуждалось в главе 8, и способность передавать данные через параметры усиливает сходство. Но в отсутствие оператора присваивания, как в языках программирования, кажется, что нельзя присвоить переменной значение, возвращаемое именованным шаблоном, впрочем, поразмыслив, это можно сделать. С шаблонами можно и еще в одном случае поступить так же, как с функциями, — осуществить рекурсивный вызов.

Рекурсивный вызов шаблонов

Эта тема предназначена, главным образом, для программистов, поскольку здесь я буду пользоваться XSLT как языком программирования. В частности, я реализую вызов именованным шаблоном самого себя, то есть рекурсивный вызов. Классический пример рекурсии — вычисление факториала: например, факториал 6, что записывается как 6!, равен 6*5*4*3*2*1, или 720.

При реализации рекурсии в настоящем языке программирования создается функция — например, factorial, которая вызывается со значением 6: factorial(6). Факториал 6 вычисляется как 6 * factorial(5), поэтому функции нужно лишь умножить на 6 результат вызова самой себя со значением 5, то есть factorial(5). 

Далее, factorial(5) — это 5*factorial(4), поэтому функция снова вызывает сама себя, чтобы вычислить значение factorial(4). Этот процесс продолжается до вычисления factorial(1), а мы знаем, что 1! — это просто 1, поэтому factorial(1) возвращает 1. С этого момента управление последовательно возвращается на все предыдущие этапы, в результате чего будет вычислено выражение 1*2*3*4*5*6, или 720, что составляет 6!.

Кажется, что в таком языке стилей, как XSLT, реализовать подобное невозможно. Тем не менее, это можно сделать, по крайней мере, в XSLT 1.0. Основная идея состоит в том, что значение, возвращаемое шаблоном, можно сохранять в переменной, если шаблон вызывается внутри элемента <xsl:variable>, в котором объявляется эта переменная. Пусть, например, у нас есть именованный шаблон factorial, и мы хотим вычислить 6!. Тогда шаблону можно передать значение 6 при помощи элемента <xsl:with-param> и присвоить строковое значение результата переменной result, которое я затем показываю:

<?xml version="1.0"?>

<xsl:stylesheet version="1.0"

 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

 <xsl:template match="/">

  <xsl:variable name="result">

   <xsl:call-template name="factorial">

    <xsl:with-param name="value" select="6"/>

   </xsl:call-template>

  </xsl:variable>

  6! = <xsl:value-of select="$result"/>

 </xsl:template>

 .

 .

 .

Следующий пример демонстрирует, как можно реализовать шаблон factorial, чтобы для вычисления факториала он вызывал сам себя. На языке программирования я мог бы написать рекурсивный вызов как n!=n*factorial(n-1), но у нас нет оператора присваивания; поэтому, когда я вычисляю factorial(n-1), я сохраняю это значение в новой переменной temp и на каждом шаге возвращаю значение n*$temp:

<?xml version="1.0"?>

<xsl:stylesheet version="1.0"

 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

 <xsl:template match="/">

  <xsl:variable name="result">

   <xsl:call-template name="factorial">

    <xsl:with-param name="value" select="6"/>

   </xsl:call-template>

  </xsl:variable>

  6! = <xsl:value-of select="$result"/>

 </xsl:template>

 <xsl:template name="factorial">

  <xsl:param name="value"/>

  <xsl:choose>

   <xsl:when test="$value=1">

    <xsl:value-of select="1"/>

   </xsl:when>

   <xsl:otherwise>

    <xsl:variable name="temp">

     <xsl:call-template name="factorial">

      <xsl:with-param name="value" select="$value - 1"/>

     </xsl:call-template>

    </xsl:variable>

    <xsl:value-of select="$temp * $value"/>

   </xsl:otherwise>

  </xsl:choose>

 </xsl:template>

</xsl:stylesheet>

Вот результирующий документ:

<?xml version="1.0" encoding="utf-8"?>

6! = 720

Как видите, это можно сделать, по крайней мере, в XSLT 1.0, в котором разрешены использованные здесь фрагменты результирующего дерева.

Шаблон: значение по умолчанию

Как я говорил ранее, в случае задания параметру значения при объявлении, оно может быть перекрыто, если вы зададите другое значение в элементе <xsl:with-param>. Но если другого значения не указывать, исходное значение выступит в роли значения по умолчанию.

Следующий пример видоизменяет рассмотренный ранее пример «COLORS». Шаблон имеет параметр COLOR, но я могу вызвать шаблон, не устанавливая COLOR в какое-либо определенное значение:

<xsl:template match="PLANET">

 <xsl:if test="NAME='Mercury'">

  <xsl:call-template name="COLORS">

   <xsl:with-param name="COLOR" select="'RED'"/>

  </xsl:call-template>

 </xsl:if>

 <xsl:if test="NAME='Venus'">

  <xsl:call-template name="COLORS">

   <xsl:with-param name="COLOR" select="'GREEN'"/>

  </xsl:call-template>

 </xsl:if>

 <xsl:if test="NAME='Earth'">

  <xsl:call-template name="COLORS">

  </xsl:call-template>

 </xsl:if>

</xsl:template>

В этом случае параметр COLOR принимает значение по умолчанию«blue» (голубой), заданное в элементе <xsl:param> в шаблоне «COLORS»:

<xsl:template match="PLANET">

 <xsl:if test="NAME='Mercury'">

  <xsl:call-template name="COLORS">

   <xsl:with-param name="COLOR" select="'RED'"/>

  </xsl:call-template>

 </xsl:if>

 <xsl:if test="NAME='Venus'">

  <xsl:call-template name="COLORS">

   <xsl:with-param name="COLOR" select="'GREEN'"/>

  </xsl:call-template>

 </xsl:if>

 <xsl:if test="NAME='Earth'">

  <xsl:call-template name="COLORS">

  </xsl:call-template>

 </xsl:if>

</xsl:template>

<xsl:template name="COLORS">

 <xsl:param name="COLOR" select="'blue'"/>

 <TR>

  <TD>

   <FONT COLOR="{$COLOR}"><xsl:value-of select="NAME"/></FONT>

  </TD>

  <TD>

   <FONT COLOR="{$COLOR}"><xsl:apply-templates select="MASS"/></FONT>

  </TD>

  <TD>

   <FONT COLOR="{$COLOR}"><xsl:apply-templates select="RADIUS"/></FONT>

  </TD>

  <TD>

   <FONT COLOR="{$COLOR}"><xsl:apply-templates select="DAY"/></FONT>

  </TD>

 </TR>

</xsl:template>

Как задавать значения шаблона в командной строке

Кроме возможностей, предоставляемых элементами <xsl:param> и <xsl:with-param>, значение параметров таблицы стилей во многих процессорах XSLT можно также задавать в командной строке. Способ зависит от конкретного процессора.

1 ... 78 79 80 81 82 ... 115 ВПЕРЕД
Перейти на страницу:

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

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