Отправляет email-рассылки с помощью сервиса Sendsay
  Все выпуски  

Web-дизайн и web-программирование: статьи, скрипты



Здравствуйте уважаемые подписчики!



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



Содежание выпуска:
» ICQ-номера
Многие хотели бы иметь красивый ICQ-номер? Думаю да, запоминается легко, можно перед друзьями похвастаться :). Я сам себе недавно купил и очень доволен. Кстати, если у Вас возникнет вопрос ко мне, можете теперь связаться и через ICQ: 6600788. Если хотите себе шести или семизначный номер, смотрите список доступных и цены на них (цены неплохие от 75 рублей) на сайте www.uinoff.narod.ru. Туже информацию можете получить по номеру 8080050. Для подписчиков нашей рассылки действует скидка 5%, главное не забудьте об этом упомянуть.
Содержание выпуска
» Рассылка о тегах
Все Вы знаете, что у нашего сайта имеется еще одна рассылка: Все теги от <a> до <xmp>.

На протяжении нескольких выпусков в ней я старался продемонстрировать примеры использования различных тегов, а также приводил их синтаксис. Как мне кажется, эта тема слишком избитая, поэтому рассылка в нынешнем виде не несет практической пользы. Сейчас я подбираю новую тему для этой рассылки, возможно это даже будет тема XSL-преобразований, возможно что-то другое. Не спешите от нее отписывать :)

Содержание выпуска
» Шаблонизация на XSLT. Приемы и примеры

Шаблонизация на XSLT. Приемы и примеры

Календарев Александр, Электронные Документы

Об авторе:
кандидат наук
эксперт в вопросах создания систем B2B
WEB разработчик компании "Агрегатор"

Прохаживаясь по страницам нашего форума (http://www.phpclub.ru/talk) и отвечая на вопросы, я пришел к выводу, что большинство спрашивающих посетителей в основных чертах знают основы применения XSLT-преобразования, но на практике сталкиваются с рядом вопросов - а как же это использовать? Про XSLT-преобразование написано много статей, и мне не хотелось бы повторяться и пересказывать теорию XSLT. В данной статье речь пойдет о некоторых приемах и хитростях XSLT-разработчика. На такое громкое название, как CookBook (книга рецептов), статья не претендует, но парой хитростей я поделюсь. Статья рассчитана на начинающих пользователей XSLT-шаблонизации, знающих хотя бы ее основы.

Начнем с азов

Получение выходного HTML-кода получается путем преобразования XSLT-процессором входных XML-данных по XSL-шаблону. Соответственно, умение организовать правильный выходной поток, т.е. наш HTML-код, состоит из умения правильно организовать XML-данные и умения правильно писать шаблоны. (Хотелось бы отметить, что использование XSLT-преобразования не ограничивается генерацией только выходного HTML-кода).

Отсюда напрашивается вывод, что, прежде чем искать ошибку в шаблонах, надо проверить сами XML-данные, т.е. их структуру и состав. Проверка организуется двумя способами: либо выводом в лог-файл, либо выводом XML-данных вместо резутьтата XSLT-процессора.

Если мы используем второй способ (вывод в браузер), то, что-бы эти данные опознал браузер как XML поток и представил в удобопонимаемом виде, необходимо выдать заголовок Content-type: text/xml:

<?
 . . .
Header( "Content-type","text/xml");
print( $xml );
?>

Необходимо отметить, что, когда пишется XSL-шаблон, то это уже не HTML, а XML, и надо руководствоваться правилами валидности XML:

  • Каждому открывающему тегу должен соответствовать закрывающий тег. Это, в основном, касается парности таких тегов, как <table>, <td>, <tr>.
  • Если тег представлен без пары (одинарный), то он должен иметь закрывающий слеш. Это в основном касается таких одинарных тегов как <br/> <img/>

Практически это означает, что нельзя перемешивать теги, должна быть четкая иерархия вложенности. Например, такие конструкции как, <b> bla-bla-bla <i> bla-bla-bla </b> bla-bla-bla</i> - валидны в HTML, но недопустимы в XML.

Tекст спецификации XML (версии 1.0) можно найти по адресу: http://citforum.ru/internet/xml/xml1_1/ или http://pyramidin.narod.ru/xml/xml1/index.htm

Использование включений

Вот уже готово ваше преобразование, осталось только придать внешний вид сгенерированной станице. Нет проблем, когда страница одна или две. Проблемы появляются, когда их больше десятка, и весь сайт надо сделать в едином стиле.

Действительно, не будешь же вносить повторяющиеся части HTML-кода в каждый шаблон. В PHP-шаблонизаторах это решалось путем включений:

%include header.tpl
 ....
// текст шаблона
 ...
%inclede footer.tpl

В XSLT-преобразованиях есть аналогичный механизм <xsl:include />.

Имеется файл main.xsl, который содержит «генеральный» шаблон, единый для всех страниц:

<xsl:template match="root">
  <HTML>
  <BODY>
    <div align="center"><b>TABLE OF PRICE </b><br/>
    <table border="0" bgcolor="#000080" cellpadding="1"
cellspacing="1">
 ....
    <xsl:apply-templates select="item" />
    </table></div>
  </BODY>
  </HTML>
</xsl:template>
</xsl:stylesheet>

В данном шаблоне есть правило: <xsl:apply-templates select="item" />, - которое применяется ко всем элементам xml-документа. Данная инструкция, может быть заменена на: <xsl:calltemplate name="item" />.

В нашем преобразовании, должна быть инструкция <xsl:include href="main.xsl" /> и, соответственно, шаблонное правило, определенное в «генеральном» шаблоне:

<xsl:stylesheet version="1.0"
xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html" encoding="Windows-1251"/>
<xsl:include href="main1.xsl" />
<xsl:template match="/">
  <xsl:apply-templates select="root" />
    <!—Вызывает правило, определенное в генеральном шаблоне -->
</xsl:template >
<!—Правила, локальных шаблонов -->
  <xsl:template match="item">
    <tr bgcolor="#ffffff" align="center">
      <td align="left">
        <xsl:value-of select="description"/>
      </td>
      <td align="center">
        <xsl:value-of select="price"/>
      </td>
    </tr>
</xsl:template >
</xsl:stylesheet>

Если мы используем в «генеральном» шаблоне инструкцию <xsl:call-template name="item" />, то вместо <xsl:template match="item"> используем именной шаблон: <xsl:template name="item">. В этом случае и технология разработки шаблонов иная.

В любом случае при использовании «генеральных» шаблонов надо придерживаться строго определенного формата выходных xml-данных.

Например, у меня есть следующая структура:

<root>
<menu>
  <item name=""/>
<! -- пункты динамически сформированного меню -->
  ...
</menu>
<<action>>
<</action>>
</root>

Под <</action>> понимается имя тега, соответствующему экшену в модуле, например, для экшена edit будет тег <edit>. Но разработка структуры - дело сугубо индивидуальное.

В заключение хотелось бы заметить, что при использовании XSLT-парсера slabotron (версия php 4) необходимо установить базовую директорию, где лежат файлы включений функцией:
xslt_set_base($xh, $filebase); Где, переменная $filebase должна содержать полный путь к директории.

Если что-то не получается.

К сожалению, существующие XSLT-процессоры не имеют средств отладки. Приходится применять «дедовские способы» и «идти по шагам к цели», т.е. идти от разработки общих шаблонов к разработке частных шаблонов. Иначе это называют проектированием сверху вниз.

Как правило, разработка шаблонов соответствует порядку разбора шаблонов, т.е. начинается с корневого элемента xml данных. Может, само обрамление дизайна – это уже дело рук самого дизайнера, но заготовку в виде пустого шаблона <xsl:template match="root"> надо предусмотреть. И пошли так далее, углубляясь по ходу обработки структуры xml данных.

Если шаблон ничего не выводит, то надо проверить:

  • вызывается ли вообще данный шаблон (применяется ли к нему шаблонное правило)
  • наличие данных, обрабатываемых данным шаблоном
  • результат преобразования.

Первое (вызывается ли вообще данный шаблон) проверяется довольно просто, заменой нашего шаблона конструкцией типа:

<xsl:template match="item">
* * * * * * * *
</xsl:template >

Если, шаблон вызывался (к нему применялось шаблонное правило), то в результирующем преобразовании увидим наши звездочки.

Несколько труднее определить, какие входные узлы обрабатывал наш шаблон. Это определяется либо копированием обрабатываемых узлов в результирующее преобразование, либо определением имени обрабатываемого тега.

Копирование узла осуществляется заменой нашего шаблона на:

<xsl:template match="item">
   <node>
      <xsl:copy-of select="."/>
   </node>
</xsl:template >

Результатом применения будет текст, содержащий значение текущего узла, обрамленного тегами <node>.

Определение имени обрабатываемого узла осуществляется заменой нашего шаблона на:

<xsl:template match="item">
   <name>
      <xsl:value-of select="name(.)"/>
   </name>
</xsl:template >

Результатом применения будет текст, содержащий имя текущего узла, обрамленного тегами <name>.

Иногда, полезно знать положение узла в контексте, тогда применим функцию position(.) к текущему узлу. Использование position (.) показывает нам динамику прохода, т.е. применение шаблонных правил к текущей ветке xml-документа. Как правило, функцию position(.) применяют в циклах <xsl:for-each>, но иногда применяют и к вызовам шаблонных правил.

Проверка результата преобразования - это моделирование части работы шаблона (или всего полностью). Как и всякое моделирование, оно заключается в подготовке входных данных, которые должны представлять часть нашего xml-документа, самого шаблонного правила, т.е. набора части задействованных шаблонов, и, соответственно, простого скрипта преобразования, суть действий которого – взять файл xml-документа с диска, файл xsl-шаблона и вывести результат преобразования.

Ближе к практике. Сортировка.

Одна из часто применяемых практических задач – это вывод отсортированной таблицы, причем критерий сортировки определен данными, т.е. при разработке шаблона мы заранее знаем только перечень критериев, по которым будет производиться сортировка. Для примера возьмем прайс-лист, который можно отсортировать по:

  • цене;
  • наименованию товара;
  • наименованию группы товаров.

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

Лично я использую для этого корневой элемент. Допустим, имеется следующая структура данных:

<root sort="type">
 . .
  <table>
    <item price="12" type=" Сувениры" name="Сувенир Мозайка">
    <item price="13" type=" Сувениры" name="Сувенир Шкатулка">
 . .
    <item price="85" type="Фотопленки" name="Пленка 12/200 Kodak">
  </table>
</root>

Значение атрибута sort корневого элемента root определяет, какой тип сортировки использовать. В данном примере используется сортировка по категориям товаров (type).

Шаблон, обрабатывающий тег <table> и «строящий» таблицу, будет выглядеть следующим образом:

<xsl:template match="/">
  <html>
    <body>
      <xsl:apply-templates select="root/table" />
    </body>
  </html>
</xsl:template >

<xsl:template match="table">
  <xsl:variable name="sort" select="//root/@sort"/>
  <table>
  <xsl:for-each select="item">
    <xsl:sort select="@name[$sort='name']"/>
    <xsl:sort select="@price[$sort='price']"/>
    <xsl:sort select="@type[$sort='type']"/>
      <tr>
        <td><xsl:value-of select="@name"/></td>
        <td><xsl:value-of select="@type"/></td>
        <td><xsl:value-of select="@price"/></td>
      </tr>
    </xsl:for-each >
  </table>
</xsl:template >

Для реализации данного шаблона использован XSLT-элемент <xsl:variable>, который определяет XSLT переменную $sort. Данная переменная содержит значение атрибута sort корневого элемента root.

Для определения критерия сортировки использовались предикаты выборки. При вычислении предиката его результат приводится к булевому типу. Синтаксически предикат заключен в квадратные скобки, т.е. конструкция типа: <xsl:sort select="@type [$sort='type']"/> - показывает, что сортировка будет осуществляться для всех узлов по ключу, соответствующему атрибуту @type, при условии, что значение переменной $sort будет равно стоковому выражению «type». Соответственно, по каждому критерию, по которому будет осуществлена сортировка, необходима своя команда <xsl:sort>.

Заключение

Конечно, кол-во всяких методов и приемов при разработке XSLT шаблонов множество и «нельзя объять необъятное». В настоящее время даже появились разные стили написания шаблонов. Я попытался охватить лишь первые этапы «Путешествия в страну Шаблонизации».

В данной статье были отражены в основном главные проблемы, с которыми сталкиваются юные XSLT-шаблонизаторы. Планируется продолжение.

Уже после написания данной статьи автор узнал о существовании инструментария XSLT-разработчика, включающее средства XSLT-отладки. Это такие программные продукты, как: xselerate, Stylus Studio, Altova XML StyleVision. Данные программные продукты являются платными.

Автор будет благодарен за любую критику данного материала, а также будет рад услышать ваши пожелания и узнать, с какими же вы сталкивались трудностями при разработке XSLT–шаблонов. Все замечания будут учтены при подготовке следующей статьи из цикла: «Шаблонизация на XSLT».



Содержание выпуска


Вот и закончился наш очередной выпуск. До новых стреч.
Ведущий рассылки, Алексей Голубев.
При публикации информации из рассылки Вам следует указывать действующую ссылку на нее.

В избранное