XSLT-преобразования. Применение языка преобразований XSLT

10.07.2019

Аннотация: Рассматривается генерация кода преобразованиями XSLT. Изучается синтаксис XSLT, особенности применения преобразований, а также выполнение таких операций, как фильтрация, сортировка, выборка по условию в шаблонах. Выполнение трансформации программным путем в C#. Преимущества и недостатки технологии.

Язык преобразований XSLT

Во второй лекции мы уже рассматривали пример с использованием XSLT . В этой лекции мы рассмотрим эту технологию более подробно. XSL (eXtensible Stylesheet Language) переводится как Расширяемый Язык Стилей, и представляет собой язык для создания стилей XML документов. XSLT(XSL Transformations) - это язык преобразований XSL и является его частью. Стиль XSLT предназначен для преобразования иерархической структуры и формата документа XML . Результатами преобразования могут стать XML - файл , текстовый файл , программный код, HTML - файл , файл в формате PDF , и так далее. Этот язык предоставляет мощные возможности для манипуляции данными, информацией, текстом в иерархическом виде.

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

XSLT был разработан консорциумом W3C (World Wide Web Consortium) . Первая версия языка XSLT 1.0 стала рекомендацией 16 ноября 1999 года, а версия XSLT 2.0 стала рекомендацией 23 января 2007 года. Обе версии используются достаточно активно, и в этой лекции мы рассмотрим ту базовую функциональность, которая является для них общей. А это значит, что рассматривать будем в основном первую версию. Также упомянем некоторые команды из второй версии.

Как работает XSLT

Модель XSLT включает в себя такие части как:

  • документы XML,
  • стили XSLT ,
  • процессор XSLT ,
  • выходные документы.

Документы XML являются входными данными, которые нужно преобразовать в другие документы. Документ стиля XSLT является корректным (well formed) документом XML и содержит набор правил для выполнения преобразования. Иными словами, документ стиля является шаблоном.

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

Процессоры XSLT имеют множество реализаций и встроены во многие браузеры вроде Internet Explorer, Firefox, Mozilla, Opera и другие. В Internet Explorer используется инструмент MSXML, разработанный Microsoft. XSLT - процессор встроен в Internet Explorer, начиная с версии 4.5. Сгенерированный результат примеров данной лекции можно просматривать путем открытия XML -файлов в одном из браузеров. В конце лекции мы рассмотрим возможности запуска трансформации программным путем, используя соответствующие классы языка программирования.

XPath

Другой частью технологии XSL является язык XPath , предназначенный для доступа к узлам документа XML путем задания путей и выражений. Язык Xpath используется в файлах стилей для навигации внутри XML -документов, определения частей исходного XML -документа, которые совпадают с одним или более заранее заданными шаблонами. При нахождении совпадения процессор XSLT применит к нему соответствующие правила из файла стиля и преобразует его в часть результирующего документа. В файлах стилей XSLT выражения XPath используются весьма интенсивно.

Применение XSLT

Язык XSLT состоит из множества инструкций, записанных в виде тегов. Имя каждой инструкции обычно начинается с символов xsl . Для выполнения трансформации документ стиля XSLT должен являться корректным документом XML .

Для преобразования документа XML необходимо добавить в начало документа инструкцию, подобную следующей:

XSL - файл стилей обычно содержит множество элементов, самым главным из которых является элемент xsl :stylesheet . Именно он указывает, что данный XML - файл является файлом стилей. Кроме него могут содержаться другие элементы, например xsl :template , xsl :value-of . Документ XML и файл стиля передается в XSLT - процессор , который обрабатывает данные файлы, выполняет преобразование и выводит результат трансформации.

Ниже представлен документ XML , содержащий список языков программирования.

C# Visual Basic Delphi Prolog Пример 5.1. Файл languages.xml

Необходимо вывести этот список в формате HTML . Для этой цели используем инструкцию xsl :for-each , которая будет применять часть шаблона к секциям документа, наименование которых указано в атрибуте select . В нашем случае укажем select="languages/language" .

Файл стилей будет применяться следующий:

Мои любимые языки:

-

Пример 5.2. Файл languages.xsl

Шаблон внутри xsl :for-each выводит содержимое каждого элемента language из languages . Для этой цели используется инструкция xsl :value-of и задаваемый атрибут select="." . Это означает, что процессор должен выбирать текст содержимого текущего элемента в документе. Кроме отражения содержимого можно задавать имена конкретных тегов, а также атрибутов для выборки значений, хранящихся в них. Примеры будут рассмотрены далее.

Откроем XML файл через Internet Explorer или другой браузер . Будет выведен такой текст:

Мои любимые языки:

  • Visual Basic
  • Delphi
  • Prolog

Одним из самых главных элементов в стиле является xsl :template . Служит для определения повторно используемого шаблона и содержит правила, по которым будет преобразован документ XML . В атрибуте match содержится выражение для отбора узлов, к которым будет применен шаблон . Также может присутствовать атрибут name . В этом случае есть возможность вызывать шаблон по имени инструкцией xsl :apply-templates .

Для повторения вывода шаблона для каждого элемента документа применяется инструкция xsl :for-each . Шаблон выполняется для каждого элемента, соответствующего условию, указанному в атрибуте select .

Инструкция xsl :value-of служит для вычисления выражения, записанного в атрибуте select с последующим выводом результата в том месте, где расположен сам элемент.

Фильтрация

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

Один из них - это применение атрибута select инструкции xsl :for-each , а второй - применение атрибута match элемента xsl :template . Применение match мы рассмотрим позже, а сейчас рассмотрим select .

Изменим немного файл с данными: добавим атрибут high , обозначающий, является ли язык из нашего списка языком высокого уровня. Также расширим сам список языков.

C# Visual Basic Delphi Prolog Assembler Java Perl Пример 5.3. Файл languages4.xml

Заметим, что значение false для атрибута high стоит только для значения "Assembler" . Изменим немного файл таблицы стилей:

Языки высокого уровня:

-
Пример 5.4. Файл languages4.xsl

В секции [@ high ="true"] мы указываем, что выбирать следует только те узлы документа, у которых атрибут high имеет значение "true" . Знак @ является символом, указывающим на то, что после него стоит имя атрибута.

Посмотрим на результат:

Языки высокого уровня:

  • Visual Basic
  • Delphi
  • Prolog

Как видим, значение "Assembler" не отображается в списке языков, то есть процессор XSLT отфильтровал данные согласно заданным условиям.

Сортировка

Кроме фильтрации другой часто применяемой операцией при генерации кода является сортировка . Атрибут order-by инструкции xsl :for-each служит для сортировки результата, для обозначения порядка прохода узлов документа при выполнении трансформации. Сортируемые поля перечисляются через точку с запятой, а также имеют перед своим названием знаки "+" или "-" , означающие сортировку по возрастанию или убыванию.

Рассмотрим немного измененный вариант документа - вместо атрибута high будем использовать элемент level , принимающий значения high или low . А имя языка запишем в элемент name .

C# high Visual Basic high Delphi high Prolog high Assembler low Java high Perl high Пример 5.5. Файл languages6.xml

В следующей таблице стилей для инструкции xsl :for-each применим атрибут order-by со значением +name , где знак плюса означает, что надо отсортировать по возрастанию.

Языки высокого уровня:

-
Пример 5.6. Файл languages6.xsl

В атрибуте select мы фильтруем по значению элемента level . Также в атрибуте select инструкции

Альтернативное введение в использование XSL Transformations в PHP при помощи Sablotron.

Данный материал следует воспринимать как альтернативное введение в использование XSLT с Sablotron в PHP.

Термины XSL и XSLT близки друг к другу, и новичкам их можно считать синонимами. Подробности, в чём же различия, описаны в спецификации XSL Transformations W3C.

Все, кто интересовался возможностями XSLT, читал стандартный пример из мануала, либо примеры, приводимые в статьях, посвящённых XSLT, на разных сайтах. Работающий пример из этой же серии:

Railroad Tycoon II Platinum экономическая стратегия PopTop software G.O.D. games 2001 Grand Prix 4 автосимулятор Geoff Crammond & Simergy Infogrames Entertainment 2002 "; $xslData = " Игры

Игры

Название жанр год разработчик издатель
"; $xh = xslt_create(); $arguments = array("/_xml" => $xmlData, "/_xsl" => $xslData); $result = @xslt_process($xh, "arg:/_xml", "arg:/_xsl", NULL, $arguments); if ($result) print ($result); else { print ("There was an error that occurred in the XSL transformation...n"); print ("tError number: " . xslt_errno($xh) . "n"); print ("tError string: " . xslt_error($xh) . "n"); exit; } ?>

Подобных примеров в Сети полно. Все они хорошо показывают, что XSL-трансформация в php работает, но после их прочтения остаётся неясным, зачем XSL нужен, скорее даже наоборот - почему XSL не нужен.

"Действительно", - подумает читатель, - "если данные лежат в базе, зачем городить огород, формируя сперва XML, а затем ещё преобразовывать через XSL? С тем же успехом это сделает класс HTML-шаблона."

После этого разочарованный программист напрочь теряет интерес к XSL и вешает на технологию ярлык "ненужная заумь".

Вам, уважаемые читатели, повезло найти такой замечательный сайт, как "php в деталях". Здесь вы прочитаете о том, что XSL может не только преобразовывать XML в HTML, но и то, как можно при помощи XSL облегчить работу с php-скриптами.

Начало работы

Приведённый выше пример, хоть и слишком прост, хорошо иллюстрирует, каким образом делается XSL-преобразование в php.

Чтобы этот код работал, нужно установить XSLT-процессор Sablotron. На виндовой машине это делается так:

1. положить iconv(-1.3).dll, expat.dll и sablot.dll в C:windowsSystem (все файлы есть в стандартном дистрибутиве php)
2. открыть C:windowsphp.ini и в нём найти параметр extension_dir. Если значение параметра - "." или нечто вроде "./", исправить на, скажем, "f:usrlocalphpextension" (или адрес директории, в которой у вас лежат/будут лежать расширения php). Теперь это будет директория расширений php.
3. положить в директорию расширений файл php_xslt.dll (это для php версии 4.2.x), либо php_sablot.dll (для версии 4.0.x)
4. в php.ini раскомментируйте строчку extension=php_xslt.dll (4.2.x) или extension=php_sablot.dll (4.0.x)

Теория

Использование XSLT позволяет отделить от php-скриптов работу по форматированию и представлению данных. Это не только уменьшение объёма кода, но и вынос большого количества логических конструкций (if, else, switch), а следовательно, облегчение работы по написанию и отладке программ. Смею утверждать, что тот, кто не пробовал работать с XSLT, не представляет себе, насколько php-кодирование облегчится.

Впрочем, не надо обольщаться: если у вас было несколько конструкций if … else в php-скрипте, они, скорее всего, появятся в том же количестве в XSL-файле.

Теперь к примерам.

Вывод списков

Все усложнения, происходящие от необходимости выводить список в удобочитаемом виде, переносятся на плечи XSL. Пример #2. Список статей на сайте с подсветкой статьи, которую читают сейчас, чередование цвета в строках и нумерация списка.

2002-05-30 Ловля ошибок в PHP Живой проект и мёртвый журнал Работа с MySQL. Часть 7. Деревья Ручная сортировка в веб-интерфейсе Как поладить дизайнеру с программистом Relax this is PHP

...

... #cccccc <

Произвольная разметка

Переводя на XML сайт с текстами (как этот), естественно хотеть сделать собственную разметку статей. Например, в контейнером important выделять очень важные места и иметь возможность выделять их не обязательно жирным шрифтом, но, может быть, цветом, CSS-стилем. Или писать цитаты как текст цитаты и иметь возможность менять стиль их оформления вместе с дизайном сайта.

Медленно продвигаясь от самого простого первого примера, многие натыкаются на эту проблему и не могут найти решения. Ведь если выделить абзац в тег И делать для него шаблон, на первый взгляд, существуют три способа вывода содержимого:

1. тег xsl:value-of выводит текст, но удаляет все теги в абзаце
2 .тег xsl:copy-of выводит копию всего содержимого (без возможности применять шаблоны к детям - внутренним тегам) и самого контейнера (что не очень красиво в HTML).
3. наконец, xsl:apply-templates применит шаблоны к детям, но пропустит текст

Проблема кажется безвыходной, но решение есть. Я использую "магические" шаблоны, которые выводят и текст и теги в нём со всеми атрибутами и без изменений. Пример #3:

Данный пример использует магические шаблоны для разбора произвольной разметки. Это позволяет избежать таких жалоб: Люди, памажите сами мы не местные! Не могу вывести теги в тексте при помощи value-of!


Запомните эти шаблоны раз и навсегда! Тогда вы сможете обрабатывать любой текст Почти любой.

Первым делом XSLT-процессор при вызове инструкции apply-templates ищет шаблон для каждого элемента. Для элемента strong шаблон есть, и именно в соответствии с ним такие элементы будут обработаны. Для гиперссылки шаблона нет, поэтому она будет выведена, как есть. Можно добавить в XSL шаблон и для ссылки, который бы выводил рядом с каждой текстовой ссылкой картинку для открытия её в новом окне:

* в шаблоне использован параметр match="a[@href]" - этот шаблон будет применён только к тем тегам ссылок, в которых есть поле href и пропустит якоря ().

Невалидный код и

Кажущаяся необходимость писать валидный XML-код так же отпугивает многих неофитов XSLT. Хорошо, с завтрашнего дня будем писать статьи только валидно, благо дома можно проверить, нет ли в тексте XML-ошибки - mismatched tag или invalid token, - с этим как-нибудь справимся. Но ведь, по-хорошему, нужно и весь архив перевести в валидный код! И я так тоже думал, когда появилась возможность переделывать сайт на XML.

Решение проблемы довольно простое: не хочешь - не пиши валидно. Пиши, как привык, - без кавычек в атрибутах тегов, используй простой
и прочее. Достаточно заключить текст в контейнер (пример ниже).

Что касается, то здесь дела такие: элемента nbsp в XML нет. Есть lt, gt, quot, но не nbsp (вполне логично - это ведь non-braking space, который относится к форматированию и придуман для HTML). Поэтому его нужно объявить в документе, либо использовать только внутри .

Пример #4:

Люди, памажите, сами мы не местные!


Запомните и эти шаблоны тоже!

Очень удобно! Большие изменения в архив вносить не придётся. Можно начать писать валидно, а продолжать как попало. А можно комбинировать эти два подхода. Чтобы не писать в архивные файлы тег CDATA, я сделал простое преобразование при помощи регулярных выражений (важно так же помнить, что один тег CDATA не должен содержать в себе другой).

$doc = preg_replace("~<(p|h|pre)>(.*?)~", "<\1>\2", $doc);

Циклы

Допустим, нам нужно сделать форму для редактирования статьи, в том числе её даты. Для удобства пользования надо сделать три раскрывающихся списка (далее - "крутилки") - дата от 1 до 31, месяц, год. Первое решение, которое приходит в голову - сделать HTML-код крутилок в php, вставить в XML в контейнере CDATA, а затем вывести в XSL с параметром disable-output-escaping="yes".

На самом деле, XSLT может и это. Достаточно вставить в данные XML число, номер месяца и год. Крутилки можно нарисовать сразу в XSLT.

Напишем шаблон, не предназначенный ни для какого элемента документа. Он будет вызываться командой xsl:call-template и получать два параметра: значение счётчика и максимум. Сперва он будет выводить нужные нам данные со значением счётчика, затем вызывать самого себя с параметрами максимум и счётчик, увеличенный на 1. Пример #5:

Февраль Март Апрель Май Июнь Июль Август Сентябрь Октябрь Ноябрь Декабрь

... 7 10 2002

... ...

Оставляю вам в качестве домашнего задания шаблон для вывода крутилки с годом.

Для всех примеров ниже использован стандарт языка XSL. Широко применяется также более современная модификация этого стандарта - язык XSLT , детальнее про который можно прочитать в \xml\XSLTutorial или MSDN.

Рассмотрим простой пример XML-файла (ex01.xml). Этот и остальные примеры можно найти в папке \xml\ XSLTForBeginers на диске.



"Заметки об XSL"

Если мы откроем этот файл в браузере Internet Explorer, то увидим тот же самый текст, который приведен выше, вместе со всеми тегами и служебной информацией. Но нам не нужны теги и служебная информация! Мы хотим видеть только ту информацию, которая относится к делу, а при помощи тегов - управлять внешним видом этой информации. Эта задача решается легко и просто: необходимо к XML-файлу добавить шаблон преобразования - XSL-файл.

Перепишем наш XML-файл в следующем виде (ex01-1.xml).




"Заметки об XSL"

И создадим XSL-файл ex01-1.xsl. Текст файла приведен ниже.






Если мы теперь откроем файл ex01-1.xsl в браузере Internet Explorer, то мы увидим, что наша задача решена, - на экране осталась только необходимая нам информация, все теги исчезли. Результат, который вы получите на экране браузера, приведен ниже.

"Заметки об XSL"

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

Перепишем XML-файл. Информационную часть изменять не будем, а шаблон укажем другой ex01-2.xml.




"Заметки об XSL"

Создадим XSL-файл ex01-2.xsl. Текст файла приведен ниже.






Если мы теперь откроем файл ex01-2.xsl в браузере Internet Explorer, то результат будет другим.

"Заметки об XSL"

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

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

XML и XSL - это исчерпывающее решение описанной выше проблемы. Фактически XML-страница - это и есть временный буфер для результатов запросов. Только вместо нестандартного и трудоемкого программирования мы теперь используем стандартный механизм XSL.

Есть и еще одно соображение, которое может быть существенным для разработчиков баз данных. Большинство современных СУБД могут форматировать результаты запроса к базе данных в виде XML-файла. То есть при построении интерфейса пользователя в рамках технологии XML и XSL мы добиваемся определенной независимости от поставщика СУБД. В части организации вывода - практически полной независимости. А эта часть весьма велика в большинстве прикладных систем, ориентированных на работу с базами данных. Конечно, помимо вывода есть еще ввод и серверная обработка бизнес-логики, но здесь вам придется искать какие-то иные решения.

Первые шаги

Разберем теперь более подробно первый пример. Напомним его текст.



"Заметки об XSL"

Первая строка информирует браузер о том, что файл имеет формат XML. Атрибут version является обязательным. Атрибут encoding не является обязательным, но если у вас в тексте есть русские буквы, то необходимо вставить этот атрибут, в противном случае XML-файл просто не будет обрабатываться, - вы получите сообщение об ошибке.

Следующие строки - это тело XML-файла. Оно состоит из элементов, которые в совокупности образуют древовидную структуру. Элементы идентифицируются тегами и могут быть вложены друг в друга.

Элементы могут иметь атрибуты, значения которых тоже могут обрабатываться в соответствии с шаблоном.

На верхнем уровне XML-файла всегда находится один элемент. То есть файл вида



"Заметки об XSL"



"Введение в CSP"

не будет обрабатываться браузером. Для преобразования в корректный XML-файл нужно добавить теги элемента верхнего уровня, например




"Заметки об XSL"



"Введение в CSP"


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

Перейдем теперь к шаблону преобразования - к XSL-файлу. Задача XSL-файла - преобразовать дерево XML-файла в другое дерево, которое, например, будет соответствовать формату HTML и может быть изображено на экране браузера с учетом форматирования, выбора шрифтов и т. п.

Для того, чтобы браузер выполнил необходимое преобразование, нужно в XML-файле указать ссылку на XSL-файл


Рассмотрим теперь текст XSL-файла






Первая строка файла содержит тег элемента xsl:stylesheet. Атрибуты элемента - номер версии и ссылка на пространство имен. Эти атрибуты элемента xsl:stylesheet являются обязательными. В нашем случае пространство имен - это все имена элементов и их атрибутов, которые могут использоваться в XSL-файле. Для XSL-файлов ссылка на пространство имен является стандартной.

Заметим, что XSL-файл является одной из разновидностей XML-файлов. Он не содержит пользовательских данных, но формат его тот же самый. Файл содержит элемент верхнего уровня xsl:stylesheet, а далее идет дерево правил преобразования.

В настоящем документе мы не будем подробно пояснять, что означает каждый элемент XSL-файла. Мы будем приводить различные примеры и показывать результат в каждом примере, что даст возможность самостоятельно сопоставить различные элементы XSL-файла и инициируемые этими элементами преобразования исходного XML-файла с пользовательской информацией. Заметьте также, что значение атрибута select и подобных со смыслом «выбрать» записывается на специальном языке XPath , о котором можно прочитать в кратце на диске \xml\XPathTutorial, а подробнее в MSDN.

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

В первом примере мы посмотрели, как с помощью элемента xsl:value-of можно вывести в HTML-формате содержание элемента (текст, заключенный между тегами). Теперь мы посмотрим, как при помощи того же самого элемента можно вывести значение атрибута элемента.

Рассмотрим следующий XML-файл ex02-1.xml

XSLT-преобразования

XSLT обладает большими возможностями для оперирования данными в документах XML. Например, при помощи таблицы стилей (stylesheet) XSLT я мог бы отформатировать данные из planets.xml в таблицу HTML. Таблицы стилей содержат правила, установленные для преобразования XML-документа, и большая часть книги посвящена созданию таблиц стилей и объяснению того, как они работают. Вот как выглядит таблица стилей XSLT planets.xsl (листинг 1.2), преобразующая данные из planets.xml в таблицу HTML (мы проанализируем ее в главе 2).

Листинг 1.2. planets.xsl

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

The Planets Table

The Planets Table

Как видите, эта таблица стилей XSLT выглядит как XML-документ - и для этого есть основания, потому что она им и является. Все таблицы стилей XSLT являются также и документами XML, а раз так, то они должны быть хорошо форматированными документами XML С этими двумя документами - planets.xml (листингом 1.1) и связанной с ним таблицей стилей, planets.xsl (листинг 1.2) - мы будем работать на протяжении всей книги, рассматривая различные возможные преобразования XSLT.

Как вы свяжете эту таблицу стилей с XML-документом planets.xml ? Как мы увидим в следующей главе, одним из способов это сделать является инструкция обработки XML , использующая два атрибута. Первый атрибут - type , который следует установить в «text/xml», чтобы указать, что используется таблица стилей XSLT. (Чтобы использовать таблицы стилей другого типа - каскадирующие таблицы стилей (CSS, cascading stylesheets), обычно использующиеся с HTML - следует задать «text/css».) Второй атрибут - href , которому следует присвоить значение URI (вспомните, что XML использует не адреса URL, а идентификаторы URI, Uniform Resource Identifier) таблицы стилей:

Mercury

.0553

58.65

1516

.983

43.4

Теперь при помощи процессора (processor) XSLT можно применить таблицу planets.xsl к planets.xml и создать новый документ, planets.html . Процессор XSLT создает новый файл planets.html , который вы можете увидеть на рис. 1.2.

Рис. 1.2. HTML-документ, созданный процессором XSLT

Как можно видеть на рис. 1.2, процессор XSLT считывает данные из planets.xml , применяет к ним правила из planets.xsl и создает HTML-таблицу в planets.html. Это наш первый пример XSLT-преобразования.

Что здесь на самом деле происходит? У нас были XML-документ, planets.xml , и таблица стилей XSLT, planets.xsl . Но каким образом они объединились для создания planets.html ?

Из книги XSLT автора Хольцнер Стивен

XSL = XSLT + XSL-FO Сам XSLT в действительности является частью более крупной спецификации - расширенного языка таблиц стилей, Extensible Stylesheet Language, или XSL. XSL предназначен для задания точного, до миллиметра, формата документов. Форматирующая часть XSL, представляющая гораздо более

Из книги Технология XSLT автора Валиков Алексей Николаевич

Преобразования XSLT-XSL XSLT позволяет работать непосредственно с содержимым документов XML. Например, у вас может быть огромный документ XML, содержащий всю бейсбольную статистику за последний сезон, однако вас может интересовать только статистика для питчеров. Чтобы извлечь

Из книги автора

Версии XSLT Спецификации XSLT разрабатывались значительно активнее, чем спецификации для всего XSL. Рекомендация XSLT 1.0 была окончательно принята 16 ноября 1999 г., и эта версия является сегодня основной версией XSLT.Затем появился рабочий проект XSLT 1.1 и, хотя первоначально он

Из книги автора

Что нужно для XSLT-преобразования Для осуществления XSLT-преобразования, такого как преобразование planets.xml в planets.html, необходим XSLT-процессор. Для преобразований документов XML можно использовать XSLT тремя способами: используя отдельные программы, называемые процессорами XSLT.

Из книги автора

XSLT-преобразования на web-серверах Можно осуществлять XSLT-преобразования на web-сервере - так чтобы XML-документ был преобразован до того, как web-сервер отправит его браузеру. Здесь самое распространенное преобразование - это преобразование документа XML в HTML, но

Из книги автора

Ресурсы XSLT В Интернете можно найти огромное количество нужных нам сведений. Имейте в виду, что все приведенные далее адреса URL легко могут измениться; списки будут актуальны столь долго, сколько этого будут хотеть люди, занимающиеся поддержкой перечисленных

Из книги автора

Утилиты XSLT В Интернете существует также много утилит XSLT - в следующем списке перечислены наиболее известные: Microsoft XSL API Extension, http://msdn.microsoft.com/downloads/webtechnology/xml/xslisapi.asp. Упрощает задачу выполнения XSLT-преобразований на стороне сервера; Microsoft XSL-to-XSLT Converter,

Из книги автора

Инструкции XSLT В теле шаблона может присутствовать ряд элементов XSLT, называемых инструкциями: ; ; ; ; ; ; ; ; ; ; ; ;

Из книги автора

Расширяемость XSLT Несмотря на кажущуюся сложность XSLT, он во многих отношениях ограничен по сравнению с языками программирования, и в процессорах XSLT сразу же начали появляться расширения XSLT. Например, Saxon представил элемент , реализуя в XSLT стандартный для

Из книги автора

Из книги автора

Отличия XSLT 1.1 от XSLT 1.0 Отсутствие result tree fragment Главное и наиболее существенное отличие XSLT 1.1 от XSLT 1.0 состоит в том, что тип данных, известный в XSLT 1.0 как result tree fragment (результирующий фрагмент дерева) в XSLT 1.1. отсутствует. Вместо него в версии 1.1 используется множество узлов,

Из книги автора

Отличия XSLT 2.0 от XSLT 1.1 Прежде чем приступить к описанию отличий второй версии XSLT от версии 1.1 (и, соответственно, 1.0), следует сделать одно существенное замечание. Лицензионные соглашения Консорциума W3 не позволяют раскрывать широкой общественности внутренние материалы

Данный раздел не претендует на роль документации по языку, а лишь кратко, по шагам объясняет, как создать свой XSLT-шаблон.

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

Рабочий стол

Определим, что нам нужно для работы:
  • Входной XML-документ
  • XHTML-макет шаблона
  • Парсер XML для склейки XML с XSL
У меня входной XML документ выдает CMS-система, в которой каждая страница с материалом собирается в XML-дерево .

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

В качестве парсера (сборщика) конечного документа можно использовать браузер. Нужно лишь указать в XML-документы путь к файлу шаблону:

Хотя, как показала практика, этот механизм довольно глючный (мне пришлось пользовать IE ). Лучше воспользоваться средствами XML-парсинга языка, на котором написана CMS-система. Я использую Parser (на нем, вообщем-то, у меня вся система и работает).

Входной XML-документ

Для начала разберемся со входным XML-документом . Для того, чтобы использовать XSL нужно иметь полное представление о его структуре.

Я использую следующую схему:


/>


Начало
/


Новости
news

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

- заголовок XML-файла . Должен идти строго с начала файла. В нем прописана версия используемого XML-языка и кодировка документа. Я как правило работаю в windows-1251 (пока так удобнее), но, по идее UTF-8 лучше.

Корневой элемент документа (можно придумать свое имя). Атрибуты:

  • Lang - язык документа. Нужен для создания мультиязычных шаблонов.
  • Id - идентификатор текущего раздела.
- таблица языков, используемых на сайте.
- блок элементов навигации:
- блок основной навигации (основная структура сайта):
- элемент структуры сайта. Атрибуты:
  • Id - идентификатор раздела.
  • Parent_id - идентификатор родительского раздела.
  • Is_published - опубликован ли раздел.
  • Dir - uri-адрес раздела. По нему формируются полные адреса.
  • Section - тип раздела. Используется если необходимо разбить меню на основное и сервисное.
- блок содержимого.
В моей CMS используется модульная структура: все наполнение сайта представляет собой модули двух видов:
  • Html - текстовый модуль. Статические модули, которые заполняет редактор сайта.
  • Com - модуль-компонента. Динамические модули, которые формируют различные программные модули CMS: новости, статистика, поисковые блоки и т.д.
В XSL-шаблонах есть разметка блоков, в которые можно размещать модули. Для определения блоков я использую простую нумерацию.

CMS при сборке страницы просто выводит в все модули, которые задействованы на странице в виде:
Атрибуты:

  • Id - идентификатор модуля.
    Container - блок-назначение (в каком блоке шаблона выводиться).
    Sorting - порядок вывода в блоке.
    Type - тип:
    • Com - модуль-компонентаю
      Html - текстовый модуль.
    Method - обработчик данных.
    Title - название модуля.
    DTD я практически не использую (лишь в самом общем виде):






















]>

Его можно вставить прямо в XML-документ . Сразу после .

Подготовка XHML-шаблона

XSL-шаблон создается на базе XHTML-шаблона (некой типовой страницы сайта). Код XHTML-страницы, при этом, должен быть валидным .

Рассмотрим по шагам процесс создания шаблона.

Проверив валидность XHML-страницы своего шаблона, для облегчения собственной работы, обозначьте в нем положение всех динамических блоков:

  • Меню (и других элементов навигации).
  • Информационных блоков страницы - то место в шаблоне, в котором будут выводиться модули сайта.
  • Заголовка/названия страницы.
Сделать это лучше всего с помощью обычных HTML-комментариев:
...


Администрирование сайта

  • Начало
  • Новости
  • Разделы

Всякие новости

Основы описания XSL-шаблонов

Все файлы XSL-шаблонов имеют следующий вид:


данные шаблона

Где: - определяет тип XML-документа и кодировку. Я использую UTF-8 (не спрашивайте, почему).
- начало и конец XSL-документа.
- начало и конец шаблона для элемента element.

Шаблоны можно условно разделить на три вида:

  • element . Применяется автоматически ко всем элементам element .
  • - шаблон, описывающий правила преобразования элемента element в режиме mode1 . Таким образом можно описать различные правила обработки элементов element .
  • - шаблон с именем template-name . Не имеет привязки к какому-либо элементу XML-документа .
Если элементы одного вида могут встречаться в различных частях структуры XML-документа (например, в XML-документе, формируемом системой элемент item используется повсеместно и имеет разное значение), то в шаблоне можно указать "структурный адрес" такого элемента:

При этом, порядок применения шаблонов иерархичный, т.е., сначала шаблон применяется к корневому элементу, а затем, к дочерним, т.е. если мы вызвали обработчик для navigation , то для вызова обработчика для navigation/sections/item нам достаточно указать адрес sections/item .

Структура папок шаблонов

Для того, чтобы хранить на одном сайте несколько модулей необходимо как-то продумать структуру их хранения в папкам. При этом, удобнее разбить шаблоны на модули по нескольким xsl-файлам . Такой подход позволит в дальнейшем повторно их использовать при создании новых шаблонов.

В простейшем варианте можно создать каталог xsl и там все складировать.

  • template_folder - каталог с файлами шаблона. Называть ее можно по имени шаблона, например my_template .
  • dtd - файлы описания основных сущностей. Могут быть полезными.
  • lang - шаблоны сообщений для различных языков (если на сайте используется их используется несколько).
  • mod - шаблоны модулей.
Нам для начала потребуется создать каталог xsl/my_template и в нем, файл layout.xsl следующего вида:



Где:
- шаблон для элемента /node() (корневого). Вместо /node() можно указать //document , т.к. он у нас являеться корневым узлом.

Копируем весь XHTML-код внутрь блока

Этот шаблон будет автоматически применяться ко всему XML-документу . В нашем случае, XSL-преобразование заменит весь XML-код на XHTML-код вашего шаблона.

Далее, необходимо в директории XSL создать файл template.xsl (где, template - название вашего шаблона), в котором размещаем следующий код:


Где:

Директива импорта внешнего XSL-файла (обрабатываеться XSL-процессором ) из указанного файла. Путь к файлу указываем относительный.

Создание шаблона для основного навигационного меню

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

Следующий шаг - создание шаблона для меню.

Меню навигации сайта строиться на основе его структуры, представленной в XML-документе в следующем виде:


Начало
/


Новости
news

Текущий раздел определяется по двум параметрам:

  • Атрибуту id у корневого элемента document - он всегда равен id текущего раздела.
  • Атрибуту hit у элемента item - если таковой имеется, то это значит, мы находимся на "главной странице раздела".
Соответственно, для того, чтобы вывести меню сайта необходимо создать шаблон для элементов:
  • sections - корневой элемент меню.
  • item - элемент меню.
При этом, необходимо учесть, что элементы item могут содержать другие элементы item , в том случае, если у раздела есть подразделы:

1. Создаем в директории xsl/my_template файл navigation.xsl следующего вида:




2. Вставляем в шаблон код нашего меню из файла layout.xsl :

  • Начало
  • Разделы
  • Новости

3. …а на его место в файле layout.xsl вставляем вызов нашего шаблона меню:

Где:
select="navigation/sections" - относительный (относительно текущего) путь-адрес элемента. При этом, будут обработаны все элементы navigation/sections .

mode="global_menu" - используем шаблон с режимом global_menu . Это нам нужно на тот случай, если нужно будет выводить еще и сервисное меню, отдельно, или "хлебные крошки", или что-еще другое на основе одной и той же ветки навигации.

4. Плюс, добавим в файл layout.xsl директиву импорта файла шаблона navigation.xsl :

5. Далее, создаем в файле navigation.xsl еще один шаблон, для обработки пунктов меню:



Где:
- вызов шаблона по имени. При этом шаблон не имеет привязки к элементу, т.е. вызывается произвольно.

- вставка-вывод значения элемента title текущего элемента. Если в параметре перед именем элемента поставить символ @ - выводиться будет значения атрибута текущего элемента.

6. Немного изменяем шаблон sections :

Где:
- обработка всех элементов item элемента sections . При этом, элементы item самих элементов item (sections/item/item ) обрабатываться не будут, т.е. выводиться только один уровень меню разделов.

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

Этот шаблон будет формировать нормальные uri-ссылки для элементов нашего меню. О нем немного позже.

7. Теперь нам необходимо доделать меню,

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






Здесь мы сталкиваемся с новой конструкцией:



…которая, собственно, и задает условную обработку XML-элементов . В качестве параметра мы задаем условие:

В нашем случае это условие равенства атрибутов ID у корневого элемента (document ) и текущего элемента (item ), которое и определяет, является ли элемент текущим.

Внутри блока располагается то, что выводиться в случае выполнения условия. В блоке - если условие не выполняется.

8. Теперь, разберем шаблон href_attribute :



/


/


Здесь мы сталкиваемся с инструкцией xsl:attribute . Она позволяет создавать атрибуты для элементов внутри которого она вызывается. В нашем случае мы вызываем ее из элемента a , соответственно, она создаст для него атрибут href , т.е. адрес.

Инструкция задает цикл обработки для всех элементов, удовлетворяющих условию. В нашем случае мы выбираем ancestor-or-self::item - ось элементов от корневого элемента до текущего по цепочке. В нашем случае это позволяет выбрать для всей цепочки узлы dir , т.е. построить полный адрес текущего узла-раздела.

Похожие статьи
 
NameMassRadiusDay