XSLT

Материал из Википедии — свободной энциклопедии
Перейти к навигации Перейти к поиску
XSLT
Орган стандартизации Консорциум Всемирной паутины
Создатель Консорциум Всемирной паутины
Создан 1999
Официальный сайт w3.org/TR/xslt
w3.org/TR/xslt20/
w3.org/standards/xml/tra…
Логотип ВикискладаМедиафайлы на Викискладе

XSLT(eXtensibleStylesheetLanguageTransformations) — язык преобразованияXML-документов. Спецификация XSLT входит в составXSLи является рекомендациейW3C.

При применениитаблицы стилейXSLT, состоящей из наборашаблонов,к XML-документу (исходное дерево) образуетсяконечное дерево,которое может бытьсериализованов виде XML-документа,XHTML-документа (только для XSLT 2.0),HTML-документа илипростого текстового файла.Правила выбора (и, отчасти, преобразования) данных из исходного дерева пишутся на языке запросовXPath.

XSLT имеет множество различных применений, в основном в областивеб-программированияи генерации отчётов. Одной из задач, решаемых языком XSLT, является отделение данных от их представления, как часть общей парадигмы MVC (англ.Model-view-controller). Другой стандартной задачей является преобразование XML-документов из однойXML-схемыв другую.

XSLT разработан рабочей группой XSLКонсорциума Всемирной паутины.

Версия 1.0 была одобрена в качестве рекомендации 16 ноября1999 года.После выхода первой версии начались работы над версией 1.1, но в2001 годуони были прекращены, а рабочая группаXSLприсоединилась к рабочей группеXQueryдля совместной работы надXPath 2.0.Впоследствии XPath 2.0 послужил основой при разработке XSLT версии 2.0.

Версия 2.0 была одобрена в качестве рекомендации 24 января2007 года.

Версия 3.0 была одобрена 8 июня 2017 года.

Процесс выполнения XSLT-преобразования

[править|править код]

В процессе выполнения XSLT-преобразования задействованы:

  • один или нескольковходныхXML-документов;
  • одна или несколькотаблиц стилейXSLT;
  • XSLT-процессор;
  • один или нескольковыходныхдокументов.

В простейшем случае XSLT-процессор получает на входе два документа — входнойXML-документ и таблицу стилей XSLT — и создаёт на их основе выходной документ.

XSLT использует языкXPathдля доступа к отдельным частям входного XML-документа и для организации вычислений.

XSLT 1.0 использует XPath 1.0, а XSLT 2.0 использует XPath 2.0.

Трансформация из XML в XSLT

[править|править код]

ИсходныйXML-документ:

<?xml version= "1.0"?>
<persons>
<personusername="MP123456">
<name>Иван</name>
<surname>Иванов</surname>
</person>
<personusername="PK123456">
<name>Пётр</name>
<surname>Петров</surname>
</person>
</persons>

Таблица XSLT-стилей (преобразования):

<?xml version= "1.0"?>
<xsl:stylesheetxmlns:xsl="http://www.w3.org/1999/XSL/Transform"version="1.0">

<xsl:outputmethod="xml"indent="yes"/>

<xsl:templatematch="persons">
<transform>
<xsl:apply-templates/>
</transform>
</xsl:template>

<xsl:templatematch="person">
<record>
<xsl:apply-templatesselect="@*|*"/>
</record>
</xsl:template>

<xsl:templatematch="@username">
<username>
<xsl:value-ofselect="."/>
</username>
</xsl:template>

<xsl:templatematch="name">
<fullname>
<xsl:apply-templates/>
<xsl:apply-templatesselect="following-sibling::surname"mode="fullname"/>
</fullname>
</xsl:template>

<xsl:templatematch="surname"/>

<xsl:templatematch="surname"mode="fullname">
<xsl:text></xsl:text>
<xsl:apply-templates/>
</xsl:template>

</xsl:stylesheet>

Результирующий XML-документ:

<?xml version= "1.0" encoding= "UTF-8"?>
<transform>
<record>
<username>MP123456</username>
<fullname>ИванИванов</fullname>
</record>
<record>
<username>PK123456</username>
<fullname>ПётрПетров</fullname>
</record>
</transform>

Трансформация из XML в XHTML

[править|править код]

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

<?xml version= "1.0" encoding= "UTF-8"?>
<?xml-stylesheet type= "text/xsl" href= "my-style.xsl"?>

<domains>
<sun.comownedBy="Sun Microsystems Inc.">
<host>
www
<use>WorldWideWebsite</use>
</host>
<host>
java
<use>Javainfo</use>
</host>
</sun.com>

<w3.orgownedBy="The World Wide Web Consortium">
<host>
www
<use>WorldWideWebsite</use>
</host>
<host>
validator
<use>webdeveloperswhowanttogetitright</use>
</host>
</w3.org>
</domains>

Стиль для XSLT-трансформации:

<?xml version= "1.0" encoding= "UTF-8"?>

<xsl:stylesheetversion="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns="http://www.w3.org/1999/xhtml">
<xsl:outputmethod="xml"indent="yes"
doctype-public="-//W3C//DTD XHTML 1.0 Strict//EN"
doctype-system="http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"/>

<!--XHTML document outline-->
<xsl:templatematch="/">
<htmlxmlns="http://www.w3.org/1999/xhtml"xml:lang="en"lang="en">
<head>
<metahttp-equiv="Content-Type"content="text/html; charset=UTF-8"/>
<title>test1</title>
<styletype="text/css">
h1{padding:10px;padding-width:100%;background-color:silver}
td,th{width:40%;border:1pxsolidsilver;padding:10px}
td:first-child,th:first-child{width:20%}
table{width:650px}
</style>
</head>
<body>
<xsl:apply-templates/>
</body>
</html>
</xsl:template>

<!--Table headers and outline-->
<xsl:templatematch="domains/*">
<h1><xsl:value-ofselect="@ownedBy"/></h1>
<p>Thefollowinghostnamesarecurrentlyinuseat
<strong><xsl:value-ofselect="local-name(.)"/></strong>
</p>
<table>
<tr><th>Hostname</th><th>URL</th><th>Usedby</th></tr>
<xsl:apply-templates/>
</table>
</xsl:template>

<!--Table row and first two columns-->
<xsl:templatematch="host">
<!--Create variable for 'url', as it's used twice-->
<xsl:variablename="url"select=
"normalize-space(concat('http://', normalize-space(node()), '.', local-name(..)))"/>
<tr>
<td><xsl:value-ofselect="node()"/></td>
<td><ahref="{$url}"><xsl:value-ofselect="$url"/></a></td>
<xsl:apply-templatesselect="use"/>
</tr>
</xsl:template>

<!--'Used by' column-->
<xsl:templatematch="use">
<td><xsl:value-ofselect="."/></td>
</xsl:template>

</xsl:stylesheet>

XHTML, который мы получаем на выходе (пробелы были добавлены для ясности):

<?xml version= "1.0" encoding= "UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd" >
<htmlxmlns="http://www.w3.org/1999/xhtml"lang="en"xml:lang="en">
<head>
<metacontent="text/html;charset=UTF-8"http-equiv="Content-Type"/>
<title>test1</title>
<styletype="text/css">
h1{padding:10px;padding-width:100%;background-color:silver}
td,th{width:40%;border:1pxsolidsilver;padding:10px}
td:first-child,th:first-child{width:20%}
table{width:650px}
</style>
</head>
<body>
<h1>SunMicrosystemsInc.</h1>
<p>Thefollowinghostnamesarecurrentlyinuseat<strong>sun.com</strong></p>
<table>
<tr>
<th>Hostname</th>
<th>URL</th>
<th>Usedby</th>
</tr>
<tr>
<td>www</td>
<td><ahref="http://www.sun.com">http://www.sun.com</a></td>
<td>WorldWideWebsite</td>
</tr>
<tr>
<td>java</td>
<td><ahref="http://java.sun.com">http://java.sun.com</a></td>
<td>Javainfo</td>
</tr>
</table>

<h1>TheWorldWideWebConsortium</h1>
<p>Thefollowinghostnamesarecurrentlyinuseat<strong>w3.org</strong></p>
<table>
<tr>
<th>Hostname</th>
<th>URL</th>
<th>Usedby</th>
</tr>
<tr>
<td>www</td>
<td><ahref="http://www.w3.org">http://www.w3.org</a></td>
<td>WorldWideWebsite</td>
</tr>
<tr>
<td>validator</td>
<td><ahref="http://validator.w3.org">http://validator.w3.org</a></td>
<td>webdeveloperswhowanttogetitright</td>
</tr>
</table>
</body>
</html>

На выходе не всегда получится обязательно правильный XHTML. В XSLT 2.0 это исправлено — добавлен метод вывода 'XHTML', наряду с 'HTML', который уже существовал в XSLT 1.0.

Применение правил шаблонов

[править|править код]

Язык XSLT является декларативным, а не процедурным. Вместо определения последовательности исполняемых операторов, этот язык определяет правила, которые будут применяться во время преобразования. Само преобразование ведётся по фиксированному алгоритму.

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

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

Каждый XSLT-процессор должен выполнить следующие шаги для подготовки к трансформации.

  1. Прочитать таблицу стилей XSLT с помощью XML-парсера и перевести его содержимое в дерево узлов (дерево таблицы стилей), согласно модели данных XPath. Синтаксические ошибки «времени компиляции» определяются на этой стадии. Таблицы стилей могут быть модульными, поэтому все включения (инструкцииxsl:include,xsl:import) также будут обработаны на этой стадии с целью объединить все шаблонные правила и иные элементы из других таблиц стилей в единое дерево таблицы стилей.
  2. Прочитать входные данные XML с помощью XML-парсера, перевести его содержимое в дерево узлов (исходное дерево), согласно модели данных XPath. XML-документ может ссылаться на другие XML-источники с помощью вызова функцийdocument().Эти вызовы обычно обрабатываются во время выполнения, так как их расположение может являться вычисляемым, а вызовы соответствующих функций могут не происходить вовсе. (Пример выше не ссылается на какие-либо другие документы.)
  3. Удалить пустые узлы из таблицы стилей XSLT, кроме тех, которые являются потомками от элементовxsl:text.Это позволяет исключить появление «лишних» пробелов.
  4. Удалить пустые текстовые узлы из исходного дерева, если инструкцииxsl:strip-spaceприсутствуют в исходном документе. Это позволяет исключить появление «лишних» пробелов. (Пример выше не использует эту возможность.)
  5. Пополнить XSLT-дерево тремя правилами, которые предоставляют поведение по умолчанию для любых типов узлов, которые могут быть встречены при обработке. Первое правило — для обработкикорневого узла;оно даёт инструкцию процессору обработать каждого потомка корневого узла. Второе правило — для любыхтекстовых узловилиузлов атрибутов;он даёт команду процессору сделать копию этого узла в результирующем дереве. Третье правило — для всехузлов комментарияиузлов-инструкций обработки;никакой операции не производится. Шаблоны, явно заданные в XSLT, могут перекрывать часть или все шаблоны-правила, заданные по умолчанию. Если шаблон не содержит явных правил, встроенные правила будут применены для рекурсивного обхода исходного дерева и только текстовые узлы будут скопированы в результирующее дерево (узлы атрибутов не будут достигнуты, так как они не являются «детьми» их родительских узлов). Полученный таким образом результат обычно нежелателен, так как он является просто конкатенацией всех текстовых фрагментов из исходного XML-документа.

Затем процессор проделывает следующие шаги для получения и сериализации результирующего дерева.

  1. Создаёт корневой узел результирующего дерева.
  2. Обрабатывает корневой узел исходного дерева. Процедура обработки узла описана ниже.
  3. Сериализует результирующее дерево, если необходимо, согласно подсказкам, описанным инструкциейxsl:output.

При обработке узла производятся следующие действия.

  1. Производится поиск наиболее подходящего шаблона правила. Это достигается проверкой соответствияшаблона(который является выражением XPath) для каждого правила, указывая узлы, для которых правило может быть применено. Каждому шаблону процессором назначается относительныйприоритетистаршинстводля облегчения разрешения конфликтов. Порядок шаблонных правил в таблице стилей также может помочь разрешению конфликтов между шаблонами, которые соответствуют одинаковым узлам, но это не оказывает влияния на порядок, в котором узлы будут обрабатываться.
  2. Template rule contents are instantiated. Элементы в пространстве имён XSLT (обычно имеющие префиксxsl:) трактуются какинструкциии имеют специальную семантику, которая указывает на то, как они должны интерпретироваться. Одни предназначены для добавления узлов в результирующее дерево, другие являются управляющими конструкциями. Не XSLT-элементы и текстовые узлы, обнаруженные в правиле, копируются, «дословно», в результирующее дерево. Комментарии и управляющие инструкции игнорируются.

Инструкцияxsl:apply-templatesпри её обработке приводит к выборке и обработке нового набора узлов. Узлы идентифицируются с помощью выражения XPath. Все узлы обрабатываются в том порядке, в котором они содержатся в исходном документе.

XSLT расширяет библиотеку функций XPath и позволяет определять XPath-переменные. Эти переменные имеют разную область видимости в таблице стилей, в зависимости от того, где они были определены и их значения могут задаваться за пределами таблицы стилей. Значения переменных не могут быть изменены во время обработки.

Хотя эта процедура может показаться сложной, однако она делает XSLT по возможностям похожей на другие языки web-шаблонов. Если таблица стилей состоит из единственного правила, предназначенного для обработки корневого узла, в результат просто копируется всё содержимое шаблона, а XSLT-инструкции (элементы 'xsl:…') заменяются вычисляемым содержимым. XSLT предлагает даже специальный формат («literal result element as stylesheet») для таких простых, одношаблонных трансформаций. Однако, возможность определять отдельные шаблоны и правила сильно увеличивает гибкость и эффективность XSLT, особенно при генерации результата, который очень похож на исходный документ.

  • Тидуэлл Д.XSLT. 2-е издание = XSLT, 2nd Edition. —СПб.:Символ-Плюс,2009. — 960 с. —1200 экз.ISBN 978-5-93286-150-9.
  • Мангано С.XSLT. Сборник рецептов = XSLT Cookbook: Solutions and Examples for XML and XSLT Developers, 2nd Edition. —СПб.:BHV,2008. — 864 с. —ISBN 978-5-9775-0292-4.
  • Кэй М.XSLT. Справочник программиста. 2-е издание = XSLT, Programmer’s Reference, 2nd Edition. —СПб.:Символ-Плюс,2002. — 1016 с. —2000 экз.ISBN 5-93286-039-1.
  • Холзнер С.XSLT. Библиотека программиста. 2-е издание = Inside XSLT. —СПб.:Питер,2002. — 544 с. —3 экз.ISBN 5-94723-271-5.