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

Итак, дерево объектов D0M построено надлежащим образом. Теперь надо его преобразовать в документ XML, страничку HTML, документ PDF или объект другого типа. Средства для выполнения такого преобразования составляют третью часть набора JAXP - пакеты javax. xml. transform, javax.xml.transform.dom, javax.xml.transform.sax, javax.xml.transform.stream, которые представляют собой реализацию языка описания таблиц стилей для преобразований XSLT (XML Stylesheet Language for Transformations) средствами Java.

Язык XSLT разработан консорциумом W3 как одна из трех частей, составляющих язык записи таблиц стилей XSL (XML Stylesheet Language). Все материалы по XSL можно посмотреть на сайте проекта http://www.w3.org/Style/XSL/ .

Интерфейсы и классы, входящие в пакеты javax. xml. trans form. *, управляют процессором XSLT, в качестве которого выбран процессор Xalan, разработанный в рамках проекта Apache Software Foundation, http://xml.apache.org/xalan-j/ .

Исходный объект преобразования должен иметь Интерфейс

Source определяет всего два метода доступа к идентификатору объекта:

public String getSystemId() ; public void setSystemId(String id);

У интерфейса source есть три реализации. Класс DOMSource подготавливает к преобразованию дерево объектов D0M, а классы SAXsource и streamSource подготавливают SAX-объект и простой поток данных. В конструкторы этих классов заносится ссылка на исходный объект - для конструктора класса DOMSource это узел дерева, для конструктора класса SAXSource - ИМЯ файла, ДЛЯ КОНСТруКТОра Класса StreamSource - ВХОДНОЙ поток. Методы этих классов позволяют задать дополнительные свойства исходных объектов преобразования.

Результат преобразования описывается интерфейсом Result. Он тоже определяет точно такие же методы доступа к идентификатору объекта-результата, как и интерфейс У тоже есть три реализации - классы

DOMResult, SAXResult И StreamResult. В КОНСТруКТОрЫ ЭТИХ классов ЗЭНОСИТ- ся ссылка на выходной объект. В первом случае это узел дерева, во втором - объект типа ContentHandler, в третьем - файл, в который будет занесен результат преобразования, или выходной поток.

Само преобразование выполняется объектом класса Transformer. Вот стандартная схема преобразования дерева объектов в документ записываемый в файл.

TransformerFactory transFactory =

TransformerFactory.newInstance();

Transformer transformer = transFactory. newTrans former () ;

DOMSource source = new DOMSource (document) ;

File newXMLFile = new File ("ntbl.xml") ;

FileOutputStream fos = new FileOutputStream(newXMLFile) ;

StreamResult result = new StreamResult(fos); transformer.transform(source, result);

Вначале методом newlnstance о создается экземпляр transFactory фабрики объектов-преобразователей. Методом

public void setAttrbute(string name, String value);

класса Trans formerFactory можно установить некоторые атрибуты экземпляра. Имена и значения атрибутов зависят от реализации фабрики.

С помощью фабрики преобразователей создается объект-преобразователь класса Transformer. При создании этого объекта в него можно занести объект, содержащий правила преобразования, например, таблицу стилей XSL.

В созданный объект класса Transformer методом public void setParameter (String name, String value) ; можно занести параметры преобразования, а методами public void setOutputProperties(Properties out); public void setOutputProperty(String name, String value);

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

Cdata_section_elements - список имен секций cdata через пробел.

Doctype _public - открытый идентификатор public преобразованного документа.

Doctype_system - системный идентификатор system преобразованного документа.

ENCODING - кодировка символов преобразованного документа, значение атрибута encoding объявления XML.

INDENT - делать ли отступы в тексте преобразованного документа. Значения этого свойства "yes" или "по".

Mediatype - МШЕ-тип содержимого преобразованного документа.

METHOD - метод вывода, одно из значений "xml", "html" или "text".

Omrr_xml_declaration - не включать объявление XML. Значения "yes" или "по".

Standalone - отдельный или вложенный документ, значение атрибута standalone объявления XML. Значения "yes" или "по".

Version - номер версии XML для атрибута version объявления XML.

Например, можно задать кодировку символов преобразованного документа следующим методом:

transformer.setOutputProperty(OutputKeys.ENCODING, "Windows-1251");

Затем в приведенном примере по дереву объектов document типа Node создается объект класса DOMSouroe - упаковка дерева объектов для последующего преобразования. По типу аргумента конструктора видно, что можно преобразовать не все дерево, а какое-либо его поддерево, записав в конструкторе класса DOMSource корневой узел поддерева.

Возможно, также, преобразование не в расширение XML, а в любой другой структурированный формат, к примеру, в (стандарты HTML и XHTML сильно похожи, но только внешне) или же просто в произвольное текстовое представление.

Слово stylesheet в названии стандарта заставляет многих проводить аналогию с другим инструментом форматирования языков разметки - (Cascading Style Sheets ) – каскадными таблицами стилей. Оба эти стандарты имеют из общего, скорее всего только это самое слово в названии. С использованием XSL можно добиться эффекта применения CSS, но CSS ни разу не аналог XSL. Вот их принципиальные отличия:

  • CSS оказывает влияние только на стиль представления данных , в то время, как XSL может легко изменить само их содержание.
  • CSS применяется на стороне клиента интернет браузером, а , так и на стороне сервера.
  • XSL является расширением XML, а CSS – отдельный формальный язык.

Стандарт XSL, в контексте преобразований XML в HTML, ближе по своему назначению к – скриптовому языку , применяемому на стороне сервера. И PHP и XSL могут существенно сократить объемы страниц интернет ресурсов, позволяя хранить только их содержимое (в базе данных или в XML файлах): без параметров стилей форматирования, самой HTML разметки, ссылок и метатегов. Более того, они могут использоваться совместно: на первом этапе средствами PHP формируется XML документ, соответствующий структуре запрашиваемой пользователем интернет страницы, а на втором этапе . На завершающем этапе все это дело форматирует и “раскрашивает” браузер уже на стороне клиента по правилам, указанным в CSS. Таким образом, экономится не только место на сервере, но и объем трафика, поскольку передаются данные в оптимальном для каждого конкретного случая XML формате.

Применением XSL весьма широкое. К примеру, XSL трансформация используется для в контексте работы в удобный для восприятия, печати и дальнейшей обработки вид. Далее вашему вниманию будет представлен обзор основных конструкций XSL, инструмент для отладки схем трансформации и пример преобразования XML отчета в HTML.

Основные элементы или синтаксис XSL

Для составления XSL преобразований необходимы знания следующих стандартов:

  1. Синтаксис или XML схема языка преобразований XSL.
  2. Язык запросов к элементам XML документа .
  3. Формат целевого документа (чаще всего HTML).

С HTML многие знакомы, про XPath можно узнать, перейдя по соответствующей ссылке, а список основных элементов XSL будет представлен ниже.

Заголовок схемы XSL трансформации

Определение заголовка схемы трансформации XSL является корневым элементом соответствующего XML документа. Файлам со схемами трансформации чаще всего дают расширения.xsl. Помимо определения пространства имен xsl, заголовок схемы трансформации может содержать параметры выведения (output) результата трансформации: xml, html или text. Если элемент output не указан явно, то его параметры определяются интерпретатором по ходу разбора схемы трансформации. Параметры вывода – различные атрибуты элемента output могут влиять на форматирование конечного результата: появление дополнительных пробелом, символов перевода каретки и т.п. Я обычно не уделяю особого внимания этому элементу, поскольку в случае преобразования в XML дополнительное форматирование или его отсутствие мне не мешает, а в случае HTML его обработка - проблемы интернет браузера. С обычным текстовым форматом вывода я не сталкивался.

Шаблон XSL

Шаблон XSL используется для применения группы преобразований к определенному фрагменту XML документа. Группа преобразований помещается внутри определения шаблона, а целевой фрагмент документа отбирается посредством XPath запроса, указанного в атрибуте match. Самый распространенный вариант запроса – имя дочерних по отношению к контексту разбора элементов. Контекстом разбора до начала преобразований является сам документ и постепенно, по мере применения XSL шаблонов, контекст перемещается по структуре документа в соответствии с результатами XPath запросов. Пример шаблона ниже.

Как видно из примера, шаблон применяется к XML элементам DataSet. В результате преобразования формируется HTML заголовок с текстом, соответствующим атрибуту Caption трансформируемого элемента, создается HTML таблица и по очереди применяются к дочерним по отношению к DataSet элементам два шаблона: с запросами элементов Columns и Records. Шаблоны для обработки элементов Columns и Records должны быть определены в схеме трансформации отдельно.

Условные операторы XSL и вызов параметризованного шаблона

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

right center

-

В процессе обработки элементов Column анализируется значение атрибута Name и в зависимости от его значения вызывается определенный шаблон. Шаблоны могут иметь имя, и для их вызова используется конструкция call-template. Сами шаблоны Name и AnyColumn определены в документе отдельно. Шаблон AnyColumn к тому же является параметризованным – принимает параметры выравнивания текста в ячейке таблицы. Каждый элемент when соответствует варианту выбора, а элемент otherwise – всем остальным вариантам. Полное описание примера трансформации будет приведено в следующем разделе.

В конце тела шаблона присутствует условный оператор, с помощью которого определяется вид пустой ячейки: если значение атрибута Caption – пустая строка, то выводим символ “-”. Обратите внимание, что шаблон, помимо условия выбора элементов Column содержит атрибут mode со значением Row. Атрибут mode можно использовать для различных шаблонов с одинаковым значением атрибута match. В ходе трансформации именно значение атрибута mode в конструкциях применения шаблона apply-template будет определять выбор шаблона. Вот пример.

и

Таким образом, если у шаблона не указано имя, то возможность его применения обусловлена контекстом трансформации в соответствии со значениями атрибута match и, дополнительно, атрибута mode. Место применения шаблона по контексту определяется конструкцией apply-template. Если шаблон имеет имя, то его можно принудительно применить к текущему контексту с использованием конструкции call-template без изменения самого контекста.

Цикл и сортировка в XSL

Язык XSL не только позволяет гибко настраивать трансформацию данных, но и проводить их предварительную сортировку. Сортировка доступна только в контексте перебора элементов, организованного циклом for-each. Какие элементы перебирать определяет атрибут select элемента for-each, а по каким данным их сортировать определяет уже атрибут select элемента sort. Значениями обоих этих атрибутов должно быть XPath выражение.

Определение параметризованного шаблона XSL и присвоение значений атрибутов

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

Обратите внимание, каким образом выходному элементу p присваивается значение атрибута align – c помощью отдельной конструкции attribute и конструкции value-of, которая обращается к значению входного параметра.

Отладчик XSL схем

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

Альтернативное введение в использование 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

... ...

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

Аннотация: Рассматривается генерация кода преобразованиями 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 инструкции

Не прошло и трёх лет с тех пор, как у меня зародилась мысль о том, что пора изучать XSLT -))). Мысль зародилась, а везде ещё стоял PHP 4 и зверствовал Salbotron , который, мягко говоря, не отличался высокой производительностью. Да и редко какой браузер мог похвастаться поддержкой этого самого XSLT. По этим соображениям изучение столь перспективного направления я отложил до лучших времён. На данный момент можно смело заявить, что эти времена настали, поскольку вышел PHP 5 с поддержкой XSLT и сносной объектной моделью, а все топовые браузеры уже сами уверенно держат преобразования, только подавай XML. :)

  • http://w3c.org - комитет по разработке и продвижению стандартов всемирной паутины Internet. На данный момент он является первоисточником практически всех веб-ориентированных стандартов и рекомендаций.
  • http://www.w3.org/TR/xml - спецификация расширяемого языка разметки XML , который является основой современного веба. На момент написания статьи доступна пятая редакция версии 1.0, а также вторая редакция версии 1.1.
  • http://www.w3.org/TR/xml-names - спецификация использования пространств имён в XML.
  • http://www.w3.org/TR/xpath - спецификация по использованию языка поиска частей XML-документа XPath .
  • http://www.w3.org/TR/xsl/ - спецификация расширенного языка стилей XSL .
  • http://www.w3.org/TR/xslt - спецификация языка преобразований XSLT .
  • http://validator.w3.org/ - валидатор HTML .
  • http://www.w3.org/TR/xhtml1/ - спецификация XHTML1.0 .

Переводы на русский язык:

  • http://www.rol.ru/news/it/helpdesk/xml01.htm - Расширяемый язык разметки XML1.0 (вторая редакция). /Радик Усманов/
  • http://www.rol.ru/news/it/helpdesk/xnamsps.htm - Пространства имен в XML. /Радик Усманов/
  • http://www.rol.ru/news/it/helpdesk/xpath01.htm - Язык XML Path (XPath ). /Радик Усманов/
  • http://www.rol.ru/news/it/helpdesk/xslt01.htm - Язык преобразований XSL (XSLT ). /Радик Усманов/

Для лучшего понимания всего происходящего я рекомендую читать спецификации в следующем порядке:

  1. XML (это основа!)
  2. пространства имён (механизм разнородного XML-кода в одном файле)
  3. XPath (язык выборки элементов из дерева структуры)
  4. XSLT (преобразования)
  5. XHTML (то, к чему нужно стремиться)

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

2. Валидный XHTML

Что такое валидный XHTML? В первую очередь, это XML-документ, который должен соответствовать спецификации XML. Во-вторую, почти обычная HTML-страница, к которой все привыкли.

Почему нужен именно XHTML? Исключительно из соображений совместимости и кросс-браузерности. Страница в XHTML будет с большей вероятностью отображаться корректно в популярных браузерах, чем обычный HTML.

Для рядового клепателя страниц словосочетание XML-документ должно означать следующее:

  1. Документ содержит объявление XML-документа в самом начале страницы:
  2. Документ содержит один корневой элемент, в котором находятся все остальные.
  3. Все элементы (тэги) должны иметь закрывающую часть (
    , ).
  4. Атрибуты всегда имеют значение, которое обязательно указывается в кавычках (одинарных или двойных). Например, "radio" disabled="disabled" /> .
  5. Управляющие символы & , < и > всегда должны маскироваться. Например, "?a=1&b=2" > & . Исключение составляет только , внутри которого спецсимволы можно не маскировать.

Также сам XHTML обязывает выполнять следующие условия:

  1. Документ должен объявлять пространство имён, в рамках которого будут использоваться элементы HTML.
  2. Документ должен объявлять DOCTYPE перед корневым элементом и указывать в нём один из типов XHTML и соответствующий DTD.

Пример простого документа XHTML1.0:

И так обо всём по порядку.

    Объявление XML-документа, в котором указывается его версия и кодировка.

    Объявление пространства имён и используемого языка.

Три версии XHTML1.0 предназначены для лучшей обратной совместимости:

  • Strict - обеспечивает наибольшее соответствие рекомендациям W3C со стороны браузеров. Однако и сам HTML-код должен следовать этим рекомендациям.
  • Transitional - менее строгое соответствие, которое заставляет браузер вести себя так, как если бы это был обычный HTML-документ.
  • Frameset - позволяет использовать фреймы.

XHTML1.1 по сути является тем же XHTML1.0 Strict и призван вытеснить другие версии XHTML1.0. Однако, по сравнению с XHTML1.0 Strict, у него есть ряд отличий :

  1. Удалён атрибут lang , его роль выполняет xml:lang . (Модуль [ XHTMLMOD ])
  2. Для элементов a и map вместо атрибута name нужно использовать атрибут id . (Модуль [ XHTMLMOD ])
  3. Доступен набор элементов ruby . (Модуль [ RUBY ])

Итак, если вам нужна наибольшая кросс-браузерность и совместимость с рекомендациями W3C, то XHTML1.1 самое оно!

Из этих соображений результатом моих преобразований будет именно XHTML1.1.

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

Что такое XSLT? Это язык преобразований XML-документа, который был разработан как часть расширенного языка стилей (XSL).

Зачем нужен XSLT? Он позволяет реализовать схему, при которой данные хранятся отдельно, а их представление отдельно. То есть, один XML-документ преобразуется с помощью другого XML-документа (XSL, в котором находятся XSLT-шаблоны) в конечный документ. Результатом может быть XML, HTML или текстовый документ любого формата.

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

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

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

За подключение стиля отвечает строка:

При этом кодировка результата будет UTF-8, несмотря на то, что исходный документ был сформирован в windows-1251. К сожалению, браузеры обычно не позволяют просмотреть код результирующего документа, но модуль XSLT в PHP5 даёт возможность передать результирующий код в переменную, которую можно сохранить в файл. Поэтому, используя PHP, я приведу исходный код результирующего документа:

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

В качестве примера я приведу XSL-стиль, который при помощи XSLT будет выводить список атрибутов исходного XML-документа с их значениями, при этом будет формироваться валидный XHTML1.1. Итак, стиль:

Файл - test.xsl
"/" > "http://www.w3.org/1999/xhtml" xml:lang="ru" > Мой первый XSLT
Мой список:
  1. background-color: #eee;
Разработчик парсера: "system-property("xsl:vendor-url")" />

Чтобы понять, как он работает, я распишу каждое действие отдельно:

    Объявление XML-документа:

    Обязательным атрибутом является определение пространства имён xsl через атрибут xmlns:xsl="http://www.w3.org/1999/XSL/Transform" .

    Следующим шагом в корневом элементе stylesheet объявляется, каким образом нужно формировать результирующий документ:

    "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd" />

    Основные атрибуты:

    • method="xml" - метод вывода документа. Результирующий документ будет в формате XML.
    • encoding="windows-1251" - кодировка результирующего документа.
    • omit-xml-declaration="no" - пропускать или нет начальное объявление XML-документа (). Может иметь значение "yes" или "no" (актуально только для html).
    • indent="yes" - формировать отступы согласно уровню вложенности. Может иметь значение "yes" или "no".
    • media-type="text/xml" - MIME-тип результирующего документа (используется только для метода вывода html).
    • doctype-public="-//W3C//DTD XHTML 1.1//EN" - тип результируюшего документа (DOCTYPE)
    • doctype-system="http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd" - ссылка на DTD

    Если метод вывода объявлен html, то значения атрибутов encoding и media-type будут подставлены в заголовок страницы ( ... ) посредством метатега.

    Объявление основного шаблона:

    Атрибут xmlns="http://www.w3.org/1999/xhtml" указывает на пространство имён xhtml, которое будет применено по умолчанию к этому элементу и всем дочерним элементам, у которых оно не задано явно.

    Атрибут xml:lang="ru" указывает на язык, в котором сформирована страница (будущая).

Эта часть стиля была нужна для формирования атрибутики валидного XHTML1.1 кода.

Теперь что касается XSLT-преобразований:

    Вставка простого текста:

    Атрибут select принимает выражение XPath, на основе которого делает выборку. Если выборка вернула список узлов, то начинает работать цикл по каждому элементу.

    В данном случае выборка вернёт список атрибутов для этого (корневого) и всех дочерних элементов.

    Проверка условия:

    В данном случае, если позиция элемента чётная (определяется вышестоящим if), то в стиль элемента

  1. будет прописан серый цвет фона.

    Вывод значений элемента:

    Этот код подставит в вышестоящий элемент строку, собранную из имени текущего элемента и его значения. Содержимое атрибута select соответствует XPath.

    Разработчик парсера: "system-property("xsl:vendor-url")" /> "system-property("xsl:vendor-url")" /> "system-property("xsl:vendor")" />

Результатом обработки этого стиля (test.xsl) станет такой код:

Результат - исходный код
"1.0" encoding="windows-1251" ?> "http://www.w3.org/1999/xhtml" xml:lang="ru" > Мой первый XSLT
Мой список:
  1. attr1 = Главный атрибут
  2. style=" background-color : #eee ; " > attr1 = мой атрибут1
  3. attr2 = мой атрибут2
  4. style=" background-color : #eee ; " > attr5 = Халявный атрибут
Разработчик парсера: libxslt

Этот код соответствует стандарту XHTML1.1 и был сформирован на основе исходного XML-документа. Для проверки можно воспользоваться валидатором от W3C, который расположен по адресу http://validator.w3.org/ .

В браузере этот код выглядит примерно так:

// Вывод кода HTML в виде текста header("Content-Type: text/plain;" ); // Объект исходного XML-документа $xml = new DOMDocument(null , "windows-1251" ); $xml ->load("test.xml" ); // Объект стиля $xsl = new DOMDocument(null , "windows-1251" ); $xsl ->load("test.xsl" ); // Создание парсера $proc = new XSLTProcessor(); // Подключение стиля к парсеру $proc ->importStylesheet($xsl ); // Обработка парсером исходного XML-документа $parsed = $proc ->transformToXml($xml ); // Вывод результирующего кода echo $parsed ; // Запись файла с результирующим кодом file_put_contents("parsed.html" , $parsed ); ?>
IE 6 FireFox 3 Opera 9.02

Дополнительную информацию по использованию XSLT в PHP5 можно найти по адресу http://ru2.php.net/manual/ru/book.xslt.php .

Мысли вслух

«Товарищи, мы стоим на краю огромной пропасти! И я предлагаю сделать большой, решительный шаг вперёд!»

2019 Антон Прибора. При копировании материалов с сайта, пожалуйста, указывайте ссылку на источник.




Top