Что такое 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
divre><?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"/> < C++ 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>
Пример 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>
Пример 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>
Сравните пример 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>
Пример 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>
В примере 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>
Атрибуты
К атрибутам можно обращаться также, как и к элементам. Надо только поставить "@" перед именем атрибута.
Пример 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>
Атрибуты можно обрабатывать аналогично элементам.
Пример 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>
Также можно выбирать элементы, которые содержат или не содержат данный атрибут. Преобразование 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>
Преобразование из примера 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>
Повторение и сортировка
Инструкция 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 (это преобразование).
|