ТЕЛЕ 2

Создание отчетов на основе xsl-трансформаций (xslt). Введение в XSLT

Для всех примеров ниже использован стандарт языка 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 -))). Мысль зародилась, а везде ещё стоял 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 Антон Прибора. При копировании материалов с сайта, пожалуйста, указывайте ссылку на источник.

Рассмотрим типичный пример рендеринга HTML.

Дан список музыкальных композиций в виде XML-документа.

Рихард Вагнер Полёт валькирии Эдвард Григ В пещере горного короля Иоган Бах Токката и фуга ре-минор Антонио Вивальди Времена года. Лето. Шторм Джузеппе Верди Триумфальный марш (Аида)

Отобразим данный документ в виде HTML ul/li списка, как это показано ниже:

Для этого используем следующее XSLT-преобразование:

]>

  • Данное преобразование вернёт нам следующий HTML:

    • Рихард Вагнер - Полёт валькирии
    • Эдвард Григ - В пещере горного короля
    • ...

    XSLT-преобразование состоит из трёх шаблонов ( xsl:template). Каждый шаблон обслуживает свою сущность, что даёт нам возможность легко вносить изменения и делает код понятным.

    Если нам надо поменять отображение списка (например, добавить атрибут class), то мы редактируем шаблон match="PlayList" .

    Если же мы хотим изменить отображение элементов списка, то тут, совершенно очевидно, что стоить менять шаблон match="Track" .

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

    Конечно, в более сложных случаях разделения добиться такого разделения бывает сложно. Очень легко прийти к ситуации, когда возникает «божественный шаблон», который делает всё, так же стоит бояться скатиться к «стрельбе дробью» кучей мелких шаблонов.

    Отладка XSLT

    Что мне очень нравится в XSLT, так это возможность отладки. Отладка помогает наглядно увидеть логику работы XSTL, структуру документа, значения переменных.

    Например, отладка поможет увидеть, что за сущность обрабатывает шаблон match="/" .

    В Visual Studio отладка XSLT запускается сочетанием клавиш ALT+F5 .

    Добавив в окно Watch XPath выражение " . " (точка), мы увидим, что текущий элемент шаблона - это корень (Root) документа. Здесь можно разместить контейнер div , или что-то относящееся ко всему XML-документу.

    Работа с сущностями XML

    Можно заметить, что в приведенных примерах присутствует сущность — Мы можем ее использовать, потому что определили ее в начале XSLT-документа

    ]>

    Таким образом, — выводится, как символ с кодом — .

    Если нужно вывести строку «как есть», то стоит использовать CDATA следующим образом:

    Элемент xsl:text

    Хочу заострить внимание на элементе xsl:text . Он позволяет контролировать, что именно будет содержать TEXT-элемент. Значимость xsl:text очевидна на практике:

    XSLT-шаблон:

  • Полученный HTML:

  • Антонио Вивальди - Времена года. Лето. Шторм
  • Как видно из примера выше, отсутствие элемента xsl:text привело к появлению в HTML лишних переводов строк и пробелов.

    Безусловно, можно писать XSLT и без xsl:text , следующим образом:

  • Такой шаблон трудночитаем и есть большая вероятность, что при сопровождении в нём будут появлятся ошибки.

    Нужно стараться, чтобы форматирование XSLT-шаблона не влияло на результат трансформации. Именно поэтому я считаю, что использовать xsl:text - это хорошая практика.

    Ветвления

    Для ветвлений в XSLT есть специальные элементы: xsl:if и xsl:choose . Но я считаю, что этими инструментами сильно злоупотребляют. Более интересен приём, позволяющий не загромождать шаблон ветвлениями.

    Рассмотрим пример реализации ветвлений:

    Дополним предыдущий пример возможностью выводить сообщение «Список пуст» в случае, если PlayList не содержит элементов Track .

    Решение с использованием xsl:choose будет таким:

    ]>

  • Решение с использованием дополнительного шаблона будет следующим:

    ]>

  • Второе решение, на мой взгляд, выглядит красивее: новая функциональность не добавила нового кода в старые шаблоны, новый шаблон максимально изолирован.

    Если понадобится добавить картинку к сообщению о пустом списке, то в первом случае скорее всего разбухнет элемент xsl:when в шаблоне match="PlayList" . А вот во втором случае изменения будут только в специализированном шаблоне.

    В предыдущем примере мы разделили две абсолютно разные ветки рендеринга элемента списка. Но что если ветки различаются незначительно? Здесь использование xsl:if и xsl:choose вполне оправдано. Но мне бы хотелось показать другой подход: использование параметра mode у элемента xsl:template .

    В следующем примере навесим разные стили на чётные и нечётные элементы списка.

    ]>

  • even odd

    Циклы и сортировка в XSLT

    Для циклов в XSLT есть элемент xsl:for-each , но схожий эффект можно получить, используя обычный xsl:apply-templates .

    Выведем список композиций, отсортированный по длительности.

    • Рихард Вагнер - Полёт валькирии - 280
    • Антонио Вивальди - Времена года. Лето. Шторм - 203
    • Иоган Бах - Токката и фуга ре-минор - 187
    • Эдвард Григ - В пещере горного короля - 163
    • Джузеппе Верди - Триумфальный марш (Аида) - 103

    ]>

    ]>

  • Как видно из кода, первый вариант короче и проще, но он нарушил принцип разделения ответственности для шаблонов. Теперь шаблон match="PlayList" стал содержать логику отображения элемента Track .

    Казалось бы, ничего страшного, но представим задачу, когда в списке встречаются композиции с Id и без. Для композиции с Id нужно отрендерить ссылку, а для остальных вывести только текст.

    Вариант с использованием xsl:for-each:

    ]>

    Вариант с использованием xsl:apply-templates:

    ]>

  • В случае xsl:for-each нам потребовалось добавлять ветвление, а в случае xsl:apply-templates - новый шаблон.

    Если бы шаблон match="PlayList" уже содержал ветвления и логику, то нам понадобилось некоторое время, чтобы разобраться, куда именно нам нужно вставить ветку. Вариант с xsl:apply-templates лишён этого недостатка, поскольку мы лишь декларируем новый шаблон, а не пытаемся внедриться в старые.

    Использование xsl:for-each имеет ещё одну большую опасность. Если вы видите произвольный участок кода внутри шаблона match="PlayList" , то предполагаете, что текущий элемент это PlayList , однако xsl:for-each меняет контекст. Увидев следующий код код:

    Вам потребуется внимательно присмотреться к контексту, чтобы понять, что select="." на самом деле выбирает текущий Track .

    Шаблон mode="TrackName" match="Track" был добавлен для избежания дублирования кода, отображаюшего название. Я не сделал этого раньше, потому что в этом не было необходимости. Как только я заметил дублирование, я провёл рефакторинг и вынес общую логику отображения в новый шаблон.

    xsl:for-each - это способ не плодить сущности. Вы просто добавляете логику отображения внутрь xsl:for-each и всё прекрасно работает. Проблемы начинаются потом, когда тело цикла разрастается, а проводить рефакторинг xsl:for-each намного сложнее, чем выносить дублированный код.

    Заключение

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

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

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

    Краткая информация

    Использует программное обеспечение.NET 3.5 XML для трансформации метаданных элемента ArcGIS или любого файла XML с использованием таблицы стилей XSLT 1.0 и для сохранения результатов в файл XML.

    Шаблоны XSLT могут использоваться для выполнения разнообразных изменений метаданных ArcGIS или файлов XML. Некоторые стили XSLT предоставлены в ArcGIS for Desktop . Их можно найти в папке <Место установки ArcGIS>\Metadata\Stylesheets . Эти стили описаны в приведенной ниже таблице.

    Следующие стили применяются для создания документов HTML, используемые для отображения информации об элементе на вкладке вкладка Описание . Они извлекают содержимое метаданных объекта и добавляют к нему инструкции по HTML-форматированию. Эти стили импортируют различные шаблоны XSLT из других файлов в папку ArcGIS_Imports ; импортированные шаблоны служат для выполнения большинства операций. Если вы заинтересованы в создании пользовательских стилей отображения, дополнительные сведения об этих стилях можно получить в документации, предоставляемой вместе с ArcGIS Metadata Toolkit .

    Следующие стили, содержащиеся в папке <Место установки ArcGIS>\Metadata\Stylesheets\gpTools , принимают метаданные элемента, обрабатывают их и сохраняют получившийся XML-документ в новый XML-файл. Целью этой операции является фильтрация метаданных элемента до их использования за пределами ArcGIS. Целью также может быть изменение метаданных элемента. В этом случае полученный XML-файл можно сохранить обратно в исходный элемент в качестве метаданных последнего, используя для этого инструмент Импортер метаданных (Metadata Importer) . Можно создать модель или скрипт , который сначала будет запускать этот инструмент с использованием стиля для обновления содержимого метаданных и тут же сохранять это содержимое обратно в элементе. Следующие стили предоставлены в ArcGIS for Desktop для выполнения некоторых строго определенных задач по обработке метаданных.

    add unique identifier.xslt