KnigaRead.com/

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

На нашем сайте KnigaRead.com Вы можете абсолютно бесплатно читать книгу онлайн Алексей Валиков, "Технология XSLT" бесплатно, без регистрации.
Перейти на страницу:

     <td><input class="flat" type="text" name="email"/></td>

    </tr>

    <tr>

     <td colspan="2">

      <xsl:text>Subject</xsl:text><BR/>

      <input type="text" name="subject"/><br/>

      <!-- В скрытом поле posted помещаем текущую дату -->

      <input type="hidden" name="posted" value="{page/date}"/><br/>

      <textarea rows="10" cols="50" name="msg"/><br/><br/>

      <input type="submit" value="Post"/>

     </td>

    </tr>

   </table>

  </form>


  <!-- Обрабатываем страницу -->

  <xsl:apply-templates select="page"/>

 </xsl:template>


 <!-- Обработка страницы -->

 <xsl:template match="page">

  <xsl:apply-templates select="messages"/>

 </xsl:template>


 <!-- Обработка сообщений -->

 <xsl:template match="messages">

  <xsl:apply-templates select="message"/>

 </xsl:template>


 <!-- Вывод сообщения -->

 <xsl:template match="message">

 

   <xsl:text>From: </xsl:text>

   <xsl:choose>

    <!-- Если e-mail не указан, выводим просто имя -->

    <xsl:when test="not(EMAIL)">

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

    </xsl:when>

    <!-- Если e-mail указан, выводим гиперссылку -->

    <xsl:otherwise>

     <A href="mailto:{EMAIL}"><xsl:value-of select="PERSON"/></A>

    </xsl:otherwise>

   </xsl:choose>

   <!-- Выводим дату записи -->

   <xsl:value-of select="concat(', ', POSTED)"/><br/>

   <!-- Если была указана тема, выводим ее -->

   <xsl:if test="SUBJECT">

    <xsl:text>Subject: </xsl:text>

    <xsl:value-of select="SUBJECT"/><BR/>

   </xsl:if>

   <HR/>

   <!-- Выводим текст сообщения -->

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

 

 </xsl:template>


</xsl:stylesheet>

Теперь займемся самим php-скриптом.

Листинг 9.5. Скрипт guestbook.php

<html>

 <head>

  <title>Guestbook</title>

  <META

   http-equiv="Content-Type"

   content="text/html; charset=windows-1251">

  <link rel="stylesheet" type="text/css" href="style.css"/>

 </head>

 <body>

  <?php

   // Загружаем входящий документ

   $sourcefile = "source.xml";

   $sourcehandle = fopen($sourcefile, "r")

    or die("Невозможно открыть входящий документ.");

   $source = fread($sourcehandle, filesize($sourcefile));

   // Загружаем преобразование

   $stylesheetfile = "stylesheet.xsl";

   $stylesheethandle = fopen($stylesheetfile, "r")

    or die("Невозможно открыть файл преобразования");

   $stylesheet = fread($stylesheethandle, filesize($stylesheetfile));

   // Инициализируем XSLT-процессор

   $xslt = @xslt_create() or die("Can't create XSLT handle!");

   // Выполняем преобразование

   @xslt_process($stylesheet, $source, $result);

   // Выводим результат

   echo $result;

   // Освобождаем ресурсы

   @xslt_free($xslt);

  ?>

 </body>

</html>

Приблизительный результат выполнения этого скрипта можно видеть на рис. 9.9.

Рис. 9.9. Сгенерированная из PHP-скрипта страница гостевой книги

Выполнение XSLT-преобразований в JavaScript

JavaScript является одним из наиболее популярных скриптовых языков, которые применяются при программировании для Web. В этой главе мы покажем, как при помощи JavaScript и MSXML создать интерактивный каталог, основанный на XML и XSLT.

Предположим, что каталог организован в виде иерархии категорий приблизительно следующим образом.

Листинг 9.6. XML-документ каталога

<?xml version="1.0" encoding="windows-1251"?>

<catalog>

 <category title="Компьютеры">

  <category title="Настольные компьютеры"/>

  <category title="Серверы"/>

 </category>

 <category title="Комплектующие">

  <category title="Процессоры"/>

  <category title="Материнские платы"/>

 </category>

 <category title="Расходные материалы">

  <category title="Картриджи">

   <category title="Картриджи для плоттеров"/>

   <category title="Картриджи для принтеров"/>

  </category>

  <category title="Тонеры"/>

  <category title="Бумага"/>

 </category>

</catalog>

При отображении этого дерева мы будем раскрывать только определенную выбранную ветвь категорий. Скажем, если пользователь выбрал категорию "Расходные материалы", показывать информацию о компьютерах мы ему не будем. Иными словами, мы будем показывать только те категории, которые являются надкатегориями выбранной. Для того чтобы сделать это как можно эффективнее, мы выполним следующие шаги.

□ При помощи ключа и уникального идентификатора, сгенерированного функцией generate-id, мы найдем в дереве требуемую категорию и присвоим ее переменной $category.

□ Воспользовавшись осью ansector-or-self, мы найдем все надкатегории данной, то есть все категории, которые прямо или косвенно содержат найденную. Путь выборки будет иметь вид $category/ancestor-or-self::category. Найденное множество мы присвоим переменной $path.

□ При обработке каждой из категорий мы будем обрабатывать ее подкатегории только в том случае, если она является надкатегорией выбранной; иначе говоря — только в том случае, когда ее узел принадлежит множеству узлов $path. Проверять это мы будем при помощи условия count(.|$path)=count($path).

Искомое преобразование в итоге запишется в виде.

Листинг 9.7. Преобразование обрабатывающее наш каталог

<?xml version="1.0" encoding="windows-1251"?>

<xsl:stylesheet

 version="1.0"

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

 <!-- Выводим документ в формате html и кодировке windows-1251 -->

 <xsl:output method="html" encoding="windows-1251"/>

 <!--

  | Переменная, которая содержит уникальный

  | идентификатор выбранного узла дерева

  +-->

 <xsl:param name="current" select="''"/>

 <!-- Определение ключа категории -->

 <xsl:key name="cat" match="category" use="generate-id(.)"/>

 <!-- Находим текущую категорию -->

 <xsl:variable name="category" select="key('cat',$current)"/>

 <!--

  | Находим надкатегории текущей категории, узлы которых

  | мы будем раскрывать в дереве

  +-->

 <xsl:variable name="path"

  select="$category/ancestor-or-self::category"/>


 <!-- Шаблон обработки каталога -->

 <xsl:template match="catalog">

  <xsl:apply-templates select="category"/>

 </xsl:template>


 <!-- Шаблон обработки категории-->

 <xsl:template match="category">

  <!-- Параметр, указывающий отступ -->

  <xsl:param name="indent"/>

  <!-- Выводим отступ -->

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

  <!-- Выводим информацию о категории в виде ссылки -->

  <а href="javascript:expand('{generate-id(.)}')">

   <!-- Перед названием категории выводим соответствующую иконку -->

   <img height="11" width="11" border="0">

    <xsl:choose>

     <!--

      | Если категория не содержит субэлементов,

      | выводим иконку с точкой

      +-->

     <xsl:when test="not(*)">

      <xsl:attribute name="src">images/dot.gif</xsl:attribute>

     </xsl:when>

     <!--

      | Если категория принадлежит ветке выбранной категории,

      | выводим иконку с минусом, что означает раскрытую ветку

      +-->

     <xsl:when test="count(.|$path)=count($path)">

      <xsl:attribute name="src">images/minus.gif</xsl:attribute>

     </xsl:when>

     <!--

      | Если категория не принадлежит ветке выбранной категории,

      | выводим иконку с плюсом, что означает нераскрытую ветку

      +-->

     <xsl:otherwise>

      <xsl:attribute name="src">images/plus.gif</xsl:attribute>

     </xsl:otherwise>

    </xsl:choose>

   </img>

   <!--

    | Выводим неразрывный пробел.

    | &#xA0; в Unicode соответствует &nbsp;

    +-->

   <xsl:text>&#xA0;</xsl:text>

   <!-- Выводим название категории -->

   <xsl:value-of select="@title"/>

  </a>

Перейти на страницу:
Прокомментировать
Подтвердите что вы не робот:*