Язык преобразований XSLT
Язык XSLT служит транслятором, с помощью которого можно свободно модифицировать исходный текст. |
Что такое XSLT?
XSLT (eXtensible Stylesheet Language Transformations) - расширяемый язык преобразования листов стилей.
Язык XSLT служит транслятором, с помощью которого можно свободно модифицировать исходный текст. XLST играет решающую роль в утверждении XML в качестве универсального языка хранения и передачи данных. Область применения XSLT широка - от электронной коммерции до беспроводного Web.
Фактическая сборка результирующего документа происходит, когда исходный документ и лист стилей XSLT передаются в синтаксический анализатор XSLT (XSLT-процессор).
При использовании XSLT в среде Web синтаксический анализ может происходить либо на стороне пользователя (т.е. в пользовательском браузере), либо на стороне сервера.
Анализ XSLT на стороне клиента похож на процедуру применения каскадных листов стилей. В исходный документ нужно добавить тег
<?xml-stylesheet type="text/xsl" href="transform.xsl" ?>
Здесь transform.xsl - имя файла листа стилей XSLT.
Шаблоны
Каждый элемент XSLT начинается префиксом xsl:. Элемент xsl:stylesheet служит контейнером для листа стилей XSLT. Атрибут version="1.0" этого элемента определяет версию спецификации XSL.
Преобразования XSLT основаны на шаблонах. Шаблон определяется инструкцией xsl:template.
XSLT-процессор анализируют исходный документ и пытается найти подходящий XSL-шаблон. Если такой шаблон найден, то выполняются инструкции внутри него.
Обработка всегда начинается с шаблона, где match="/". Это значение пути адресации соответствует корневому узлу (в примере 1 это книга).
Пример 1
Исходный XML
<?xml version="1.0" encoding="WINDOWS-1251" ?> <?xml-stylesheet type="text/xsl" href="t01.xsl" ?> <книга> <название>Мастер и Маргарита</название> <автор>Михаил Булгаков</автор> </книга>
Преобразование XSLT ( файл t01.xsl )
<?xml version="1.0" encoding="WINDOWS-1251" ?> <xsl:stylesheet version = "1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:template match="/"> <h1 align="center"> <xsl:value-of select="//название"/> </h1> <h2 align="right"> <xsl:value-of select="//автор"/> </h2> </xsl:template> </xsl:stylesheet>
Мастер и Маргарита
Михаил Булгаков
Содержание элементов может быть извлечено из исходного документа двумя основными способами:
- инструкцией xsl:value-of. В этом случае содержание элемента используется без какой-либо дальнейшей обработки (см. пример 2);
- инструкцией xsl:apply-templates. В этом случае XSLT-процессор продолжает обрабатывать выбранные элементы, для которых определен шаблон (см. пример 3).
Пример 2
Исходный XML
<?xml version="1.0" encoding="WINDOWS-1251" ?> <?xml-stylesheet type="text/xsl" href="t02.xsl" ?> <книга> <название>Мастер и Маргарита.</название> <автор>Михаил Булгаков</автор> </книга>
Преобразование XSLT ( файл t02.xsl )
<?xml version="1.0" encoding="WINDOWS-1251" ?> <xsl:stylesheet version = "1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:template match="/"> <h2> <xsl:value-of select="."/> </h2> </xsl:template> <xsl:template match="автор"> <i> <xsl:value-of select="."/> </i> </xsl:template> </xsl:stylesheet>
Мастер и Маргарита. Михаил Булгаков
Пример 3
Исходный XML
<?xml version="1.0" encoding="WINDOWS-1251" ?> <?xml-stylesheet type="text/xsl" href="t03.xsl" ?> <книга> <название>Мастер и Маргарита.</название> <автор>Михаил Булгаков</автор> </книга>
Преобразование XSLT ( файл t03.xsl )
<?xml version="1.0" encoding="WINDOWS-1251" ?> <xsl:stylesheet version = "1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:template match="/"> <h2> <xsl:apply-templates/> </h2> </xsl:template> <xsl:template match="автор"> <i>  <xsl:value-of select="."/> </i> </xsl:template> </xsl:stylesheet>
Мастер и Маргарита. Михаил Булгаков
В качестве значений атрибутов match и select используются выражения, синтаксис которых похож на маршрут файловой системы:
Выражение | Описание
|
/ | Корневой узел |
. | Текущий узел |
.. | Родительский узел текущего узла |
fruit | Узел fruit |
fruit/lime | Подузел lime узла fruit |
fruit/* | Все потомки узла fruit |
/fruit | Узел fruit, являющийся прямым потомком корневого узла |
@taste | Атрибут taste текущего узла |
@* | Все атрибуты текущего узла |
fruit@taste | Атрибут taste узла fruit |
fruit/lime@taste | Атрибут taste узла lime, являющегося подузлом узла fruit |
..@taste | Атрибут taste родительского узла |
// | Любое количество промежуточных узлов |
fruit//lime | Все узлы lime, имеющие предка fruit |
| | Знак разделения конкретных узлов |
lime|grape | Узел lime и узел grape |
[] | Предикатное выражение |
fruit[lime] | Узел fruit, имеющий потомка lime |
fruit[lime="fine"] | Узел fruit, имеющий потомка lime, значение которого равно fine |
fruit[@taste] | Узел fruit, имеющий атрибут taste |
fruit[@taste="5"] | Узел fruit, имеющий атрибут taste, значение которого равно 5 |
count(fruit/*) | Количество потомков узла fruit |
name() | Имя текущего узла |
Сравните результаты примера 4 (перечисление узлов) и примера 5 (все узлы).
Пример 4
Исходный XML
<?xml version="1.0" encoding="WINDOWS-1251" ?> <?xml-stylesheet type="text/xsl" href="t04.xsl" ?> <книга> <название>Мастер и Маргарита</название> <автор>Михаил Булгаков</автор> </книга>
Преобразование XSLT ( файл t04.xsl )
<?xml version="1.0" encoding="WINDOWS-1251" ?> <xsl:stylesheet version = "1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:template match="название|автор"> <div> [шаблон "<xsl:value-of select="name()"/>" содержит "<xsl:apply-templates/>" ] </div> </xsl:template> </xsl:stylesheet>
Пример 5
Исходный XML
<?xml version="1.0" encoding="WINDOWS-1251" ?> <?xml-stylesheet type="text/xsl" href="t05.xsl" ?> <книга> <название>Мастер и Маргарита</название> <автор>Михаил Булгаков</автор> </книга>
Преобразование XSLT ( файл t05.xsl )
<?xml version="1.0" encoding="WINDOWS-1251" ?> <xsl:stylesheet version = "1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:template match="*"> <div> [шаблон "<xsl:value-of select="name()"/>" содержит "<xsl:apply-templates/>" ] </div> </xsl:template> </xsl:stylesheet>
В путях адресации очень часто встречается "//". В начале пути адресации он обозначает: выбрать все узлы определенного типа в документе (пример 6). Внутри пути адресации он обозначает: выбрать все узлы, являющиеся потомками узла, указанного в первой части пути адресации (пример 7).
Пример 6
Исходный XML
<?xml version="1.0" encoding="WINDOWS-1251" ?> <?xml-stylesheet type="text/xsl" href="t06.xsl" ?> <source> <AAA id="a1"> <BBB id="b1"/> <BBB id="b2"/> </AAA> <AAA id="a2"> <BBB id="b3"/> <BBB id="b4"/> <CCC id="c1"> <DDD id="d1"/> </CCC> <BBB id="b5"> <CCC id="c2"/> </BBB> </AAA> </source>
Преобразование XSLT ( файл t06.xsl )
<?xml version="1.0" encoding="WINDOWS-1251" ?> <xsl:stylesheet version = "1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:template match="/"> <xsl:apply-templates select="//BBB"/> <xsl:apply-templates select="//CCC"/> <xsl:apply-templates select="//DDD"/> <xsl:apply-templates select="//AAA"/> </xsl:template> <xsl:template match="AAA"> <div style="color:navy"> <xsl:value-of select="name()"/> <xsl:text> id=</xsl:text> <xsl:value-of select="@id"/> </div> </xsl:template> <xsl:template match="BBB"> <div style="color:purple"> <xsl:value-of select="name()"/> <xsl:text> id=</xsl:text> <xsl:value-of select="@id"/> </div> </xsl:template> <xsl:template match="CCC"> <div style="color:red"> <xsl:value-of select="name()"/> <xsl:text> id=</xsl:text> <xsl:value-of select="@id"/> </div> </xsl:template> <xsl:template match="DDD"> <div style="color:blue"> <xsl:value-of select="name()"/> <xsl:text> id=</xsl:text> <xsl:value-of select="@id"/> </div> </xsl:template> </xsl:stylesheet>
Пример 7
Исходный XML
<?xml version="1.0" encoding="WINDOWS-1251" ?> <?xml-stylesheet type="text/xsl" href="t07.xsl" ?> <source> <AAA id="a1"> <BBB id="b1"/> <BBB id="b2"/> </AAA> <AAA id="a2"> <BBB id="b3"/> <BBB id="b4"/> <CCC id="c1"> <DDD id="d1"/> </CCC> <BBB id="b5"> <CCC id="c2"/> </BBB> </AAA> </source>
Преобразование XSLT ( файл t07.xsl )
<?xml version="1.0" encoding="WINDOWS-1251" ?> <xsl:stylesheet version = "1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:template match="/"> <xsl:apply-templates select="/source/AAA//CCC"/> <xsl:apply-templates select="/source//AAA/BBB//*"/> </xsl:template> <xsl:template match="AAA"> <div style="color:navy"> <xsl:value-of select="name()"/> <xsl:text> id=</xsl:text> <xsl:value-of select="@id"/> </div> </xsl:template> <xsl:template match="BBB"> <div style="color:purple"> <xsl:value-of select="name()"/> <xsl:text> id=</xsl:text> <xsl:value-of select="@id"/> </div> </xsl:template> <xsl:template match="CCC"> <div style="color:red"> <xsl:value-of select="name()"/> <xsl:text> id=</xsl:text> <xsl:value-of select="@id"/> </div> </xsl:template> <xsl:template match="DDD"> <div style="color:blue"> <xsl:value-of select="name()"/> <xsl:text> id=</xsl:text> <xsl:value-of select="@id"/> </div> </xsl:template> </xsl:stylesheet>
С помощью режимов mode элемент может быть обработан многократно, причем каждый раз с различным результатом.
Пример 8
Исходный XML
<?xml version="1.0" encoding="WINDOWS-1251" ?> <?xml-stylesheet type="text/xsl" href="t08.xsl" ?> <source> <AAA id="a1"> <BBB id="b1"/> <BBB id="b2"/> </AAA> <AAA id="a2"> <BBB id="b3"/> <BBB id="b4"/> <CCC id="c1"> <CCC id="c2"/> </CCC> <BBB id="b5"> <CCC id="c3"/> </BBB> </AAA> </source>
Преобразование XSLT ( файл t08.xsl )
<?xml version="1.0" encoding="WINDOWS-1251" ?> <xsl:stylesheet version = "1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:template match="/"> <xsl:apply-templates select="//CCC" mode="red"/> <xsl:apply-templates select="//CCC" mode="blue"/> <xsl:apply-templates select="//CCC"/> </xsl:template> <xsl:template match="CCC" mode="red"> <div style="color:red"> <xsl:value-of select="name()"/> <xsl:text> id=</xsl:text> <xsl:value-of select="@id"/> </div> </xsl:template> <xsl:template match="CCC" mode="blue"> <div style="color:blue"> <xsl:value-of select="name()"/> <xsl:text> id=</xsl:text> <xsl:value-of select="@id"/> </div> </xsl:template> <xsl:template match="CCC"> <div style="color:purple"> <xsl:value-of select="name()"/> <xsl:text> id=</xsl:text> <xsl:value-of select="@id"/> </div> </xsl:template> </xsl:stylesheet>
Достаточно часто несколько шаблонов соответствует одному и тому же элементу в исходном XML. Поэтому надо решить, какой из них следует использовать. Для этого можно определить приоритеты с помощью атрибута priority. Если этот атрибут не определен, его приоритет вычисляется в соответствии с несколькими правилами. Вычисленные приоритеты располагаются в диапозоне от -0.5 до 0.5. Более подробная информация содержится в Спецификации XSLT.
Для примеров 9-14 исходным является XML из примера 8.
Пример 9 и пример 10 различаются приоритетами их шаблонов.
Пример 9
Преобразование XSLT
<xsl:stylesheet version = "1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:template match="/"> <xsl:apply-templates select="//CCC"/> </xsl:template> <xsl:template match="CCC" priority="3"> <h3 style="color:blue"> <xsl:value-of select="name()"/> <xsl:text> id=</xsl:text> <xsl:value-of select="@id"/> </h3> </xsl:template> <xsl:template match="CCC/CCC" priority="4"> <h2 style="color:red"> <xsl:value-of select="name()"/> <xsl:text> id=</xsl:text> <xsl:value-of select="@id"/> </h2> </xsl:template> </xsl:stylesheet>
CCC id=c1
CCC id=c2
CCC id=c3
Пример 10
Преобразование XSLT
<xsl:stylesheet version = "1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:template match="/"> <xsl:apply-templates select="//CCC"/> </xsl:template> <xsl:template match="CCC" priority="4"> <h3 style="color:blue"> <xsl:value-of select="name()"/> <xsl:text> id=</xsl:text> <xsl:value-of select="@id"/> </h3> </xsl:template> <xsl:template match="CCC/CCC" priority="3"> <h2 style="color:red"> <xsl:value-of select="name()"/> <xsl:text> id=</xsl:text> <xsl:value-of select="@id"/> </h2> </xsl:template> </xsl:stylesheet>
CCC id=c1
CCC id=c2
CCC id=c3
Пример 11 показывает действие по умолчанию в отсутствие атрибутов priority. Шаблон CCC имеет меньший приоритет по сравнению с CCC/CCC, поскольку он менее специфичный.
Пример 11
Преобразование XSLT
<xsl:stylesheet version = "1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:template match="/"> <xsl:apply-templates select="//CCC"/> </xsl:template> <xsl:template match="CCC"> <h3 style="color:blue"> <xsl:value-of select="name()"/> <xsl:text> id=</xsl:text> <xsl:value-of select="@id"/> </h3> </xsl:template> <xsl:template match="CCC/CCC"> <h2 style="color:red"> <xsl:value-of select="name()"/> <xsl:text> id=</xsl:text> <xsl:value-of select="@id"/> </h2> </xsl:template> </xsl:stylesheet>
CCC id=c1
CCC id=c2
CCC id=c3
Сравните пример 12 и пример 13. Шаблоны CCC/CCC и AAA/CCC/CCC имеют одинаковый приоритет, и он выше, чем приоритет CCC. XSLT-процессор выбирает среди шаблонов с равным приоритетом тот, который будет последним в преобразовании, или сообщает об ошибке.
Пример 12
Преобразование XSLT
<xsl:stylesheet version = "1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:template match="/"> <xsl:apply-templates select="//CCC"/> </xsl:template> <xsl:template match="CCC"> <h3 style="color:blue"> <xsl:value-of select="name()"/> <xsl:text> id=</xsl:text> <xsl:value-of select="@id"/> </h3> </xsl:template> <xsl:template match="CCC/CCC"> <h2 style="color:red"> <xsl:value-of select="name()"/> <xsl:text> id=</xsl:text> <xsl:value-of select="@id"/> </h2> </xsl:template> <xsl:template match="AAA/CCC/CCC"> <h2 style="color:green"> <xsl:value-of select="name()"/> <xsl:text> id=</xsl:text> <xsl:value-of select="@id"/> </h2> </xsl:template> </xsl:stylesheet>
CCC id=c1
CCC id=c2
CCC id=c3
Пример 13
Преобразование XSLT
<xsl:stylesheet version = "1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:template match="/"> <xsl:apply-templates select="//CCC"/> </xsl:template> <xsl:template match="CCC"> <h3 style="color:blue"> <xsl:value-of select="name()"/> <xsl:text> id=</xsl:text> <xsl:value-of select="@id"/> </h3> </xsl:template> <xsl:template match="AAA/CCC/CCC"> <h2 style="color:green"> <xsl:value-of select="name()"/> <xsl:text> id=</xsl:text> <xsl:value-of select="@id"/> </h2> </xsl:template> <xsl:template match="CCC/CCC"> <h2 style="color:red"> <xsl:value-of select="name()"/> <xsl:text> id=</xsl:text> <xsl:value-of select="@id"/> </h2> </xsl:template> </xsl:stylesheet>
CCC id=c1
CCC id=c2
CCC id=c3
В примере 14 менее специфичный "*" имеет меньший приоритет по сравнению с CCC.
Пример 14
Преобразование XSLT
<xsl:stylesheet version = "1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:template match="/"> <xsl:apply-templates select="//CCC"/> <xsl:apply-templates select="//AAA"/> </xsl:template> <xsl:template match="CCC"> <h3 style="color:blue"> <xsl:value-of select="name()"/> <xsl:text> id=</xsl:text> <xsl:value-of select="@id"/> </h3> </xsl:template> <xsl:template match="*"> <h3 style="color:green"> <xsl:value-of select="name()"/> <xsl:text> id=</xsl:text> <xsl:value-of select="@id"/> </h3> </xsl:template> </xsl:stylesheet>
CCC id=c1
CCC id=c2
CCC id=c3
AAA id=a1
Атрибуты
К атрибутам можно обращаться также, как и к элементам. Надо только поставить "@" перед именем атрибута.
Пример 15
Исходный XML
<?xml version="1.0" encoding="WINDOWS-1251" ?> <?xml-stylesheet type="text/xsl" href="t15.xsl" ?> <полка1> <книга isbn="5-7890-0248X"> <данные название="Web-технологии" автор="Колесников Д.Г."/> </книга> </полка1>
Преобразование XSLT ( файл t15.xsl )
<?xml version="1.0" encoding="WINDOWS-1251" ?> <xsl:stylesheet version = "1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:template match="книга"> <p> <b> <xsl:text>ISBN: </xsl:text> </b> <xsl:value-of select="@isbn"/> </p> <p> <b> <xsl:text>Автор: </xsl:text> </b> <xsl:value-of select="данные/@автор"/> </p> <p> <b> <xsl:text>Название: </xsl:text> </b> <xsl:value-of select="данные/@название"/> </p> </xsl:template> </xsl:stylesheet>
ISBN: 5-7890-0248X
Автор: Колесников Д.Г.
Название: Web-технологии
Атрибуты можно обрабатывать аналогично элементам.
Пример 16
Исходный XML
<?xml version="1.0" encoding="WINDOWS-1251" ?> <?xml-stylesheet type="text/xsl" href="t16.xsl" ?> <полка1> <книга isbn="5-7890-0248X">"Web-технологии" </книга> </полка1>
Преобразование XSLT ( файл t16.xsl )
<?xml version="1.0" encoding="WINDOWS-1251" ?> <xsl:stylesheet version = "1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:template match="книга"> <xsl:value-of select="."/> <xsl:text> [</xsl:text> <xsl:apply-templates select="@isbn"/> <xsl:text>]</xsl:text> </xsl:template> <xsl:template match="@isbn"> <b> <xsl:value-of select="."/> </b> </xsl:template> </xsl:stylesheet>
"Web-технологии" [5-7890-0248X]
Также можно выбирать элементы, которые содержат или не содержат данный атрибут. Преобразование XSLT из примера 17 включает элементы, если определенный атрибут присутствует.
Пример 17
Исходный XML
<?xml version="1.0" encoding="WINDOWS-1251" ?> <?xml-stylesheet type="text/xsl" href="t17.xsl" ?> <source> <BBB id="b1" checked="yes"/> <BBB id="b2" checked="yes"/> <BBB id="b3"/> </source>
Преобразование XSLT ( файл t17.xsl )
<?xml version="1.0" encoding="WINDOWS-1251" ?> <xsl:stylesheet version = "1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:template match="BBB[@checked]"> <p> <xsl:text>BBB: </xsl:text> <xsl:value-of select="@id"/> </p> </xsl:template> </xsl:stylesheet>
BBB: id=b1
BBB: id=b2
Преобразование из примера 18 исключает элементы, содержащие указанный атрибут.
Пример 18
Преобразование XSLT
<?xml version="1.0" encoding="WINDOWS-1251" ?> <xsl:stylesheet version = "1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:template match="BBB[not(@checked)]"> <p> <xsl:text>BBB: </xsl:text> <xsl:value-of select="@id"/> </p> </xsl:template> </xsl:stylesheet>
BBB: id=b3
Повторение и сортировка
Инструкция xsl:for-each определяет шаблон, который применяется для каждого узла, выбранного с помощью атрибута select. Таким образом, инструкцию xsl:for-each можно использовать для организации простых циклов.
Пример 19
Исходный XML
<?xml version="1.0" encoding="WINDOWS-1251" ?> <?xml-stylesheet type="text/xsl" href="t19.xsl" ?> <source> <AAA id="a1"> <BBB id="b1"/> <BBB id="b2"/> </AAA> <AAA id="a2"> <BBB id="b3"/> <BBB id="b4"/> <CCC id="c1"> <DDD id="d1"/> </CCC> <BBB id="b5"> <CCC id="c2"/> </BBB> </AAA> </source>
Преобразование XSLT ( файл t19.xsl )
<?xml version="1.0" encoding="WINDOWS-1251" ?> <xsl:stylesheet version = "1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:template match="/"> <xsl:for-each select="//BBB"> <div style="color:purple"> <xsl:value-of select="name()"/> <xsl:text> id=</xsl:text> <xsl:value-of select="@id"/> </div> </xsl:for-each> <xsl:for-each select="/AAA/CCC"> <div style="color:navy"> <xsl:value-of select="name()"/> <xsl:text> id=</xsl:text> <xsl:value-of select="@id"/> </div> </xsl:for-each> </xsl:template> </xsl:stylesheet>
Оси
Оси играют очень важную роль в XSLT. Для более подробной информации читайте XSLT reference. Сравните: ось child (это преобразование), ось descendant (это преобразование), ось parent (это преобразование), ось ancestor (это преобразование), ось following-sibling (это преобразование), ось preceding-sibling (это преобразование), ось following (это преобразование), ось preceding (это преобразование), ось attribute (это преобразование), ось namespace (это преобразование), ось self (это преобразование), ось descendant-or-self (это преобразование), ось ancestor-or-self (это преобразование).
« Назад