XSLT-преобразования¶
ℹ️ XSLT (eXtensible Stylesheet Language Transformations) — язык преобразования XML-документов. В "Первой Форме" шаблон XSLT используется для преобразования данных, полученных из опубликованных SQL View, в определенный XML формат, соответствующий потребностям какой-либо внешней системы.
XSLT использует язык XPath для доступа к отдельным частям входного XML-документа и для организации вычислений.
ℹ️ По возможности преобразования данных следует выполнять на стороне SQL View, а не средствами XPath. Например, преобразование данных из денежного формата в числовой, очистку ДП типа "Большой текст с форматированием" от html-тегов и другие подобные операции оптимальнее выполнять уже при создании SQL View. .
Выражения XPath¶
С помощью выражений XPath для выбора узлов в документе XML можно выбрать узел, следуя пути или шагам.
Полезные выражения для формирования пути¶
Выражение
Описание
имя_узла
Выбирает все узлы с именем имя_узла
/
Выбирает от корневого узла
ℹ️ Если путь начинается с косой черты (/), он всегда представляет собой абсолютный путь к элементу!
//
Выбирает все узлы от текущего узла, которые соответствуют выбору, независимо от того, где они находятся
.
Выбирает текущий узел
..
Выбирает родителя текущего узла
@
Выбирает атрибуты
Примеры¶
ℹ️ Ниже приведены учебные примеры на стандартном XML. В реальных задачах замените структуру XML на данные объектов 1Форма (задачи, дополнительные параметры).
bookstore
Выбирает все узлы с именем bookstore
/bookstore
Выбирает корневой элемент
bookstore/book
Выбирает все элементы book, которые являются потомками элемента bookstore
//book
Выбирает все элементы book независимо от того, где они находятся в документе
bookstore//book
Выбирает все элементы book, которые являются потомками элемента bookstore, независимо от того, где они находятся в ветви bookstore
//\@lang
Выбирает все атрибуты, которые называются lang
Предикаты¶
Предикаты используются для поиска специфического узла или узла, который содержит специфическое значение. Предикаты всегда обрамляются квадратными скобками
Пример выражения Результат /bookstore/book\1\ Выбирает первый элемент book, который является потомком элемента bookstore /bookstore/book\last()\ Выбирает последний элемент book, который является дочерним элементом элемента bookstore /bookstore/book\last()-1\ Выбирает предпоследний элемент book, который является дочерним элементом элемента bookstore /bookstore/book\position()\<3\ Выбор первых двух элементов book, которые являются потомками элемента bookstore //title\@lang\ Выбирает все элементы title, которые имеют атрибут с именем lang //title\@lang=\'en\'\ Выбирает все элементы title, которые имеют атрибут lang со значением "en" /bookstore/book\price>35.00\ Выбирает все элементы book после элемента bookstore, которые имеют элемент price со значением больше, чем 35.00 /bookstore/book\price>35.00\/title Выбирает все элементы title элементов book из элемента bookstore, которые имеют элемент price со значением больше чем 35.00
Выбор неизвестных узлов¶
Wildcard
Результат
*
Соответствует любому узлу
@*
Соответствует узлу-атрибуту
node()
Соответствует любому узлу любого типа
//*
Выбирает все элементы в документе
Примеры¶
/bookstore/*
Выбирает все дочерние узлы элемента bookstore
//title\@*\
Выбирает все элементы title, которые имеют по крайней мере один атрибут любого вида
Выбор нескольких путей¶
Пример пути Результат //book/title | //book/price Выбирает все элементы title И price всех элементов book //title | //price Выбирает все элементы title И price в документе /bookstore/book/title | //price Выбирает все элементы title элемента book элемента bookstore И все элементы price в документе
Элементы XPath¶
Элемент \<xsl:stylesheet>:
Задает элемент документа в XSLT-файле, который содержит все остальные XSLT-элементы. Этот элемент является синонимом элемента \<xsl:transform>. \<xsl:stylesheet>\ id = id\ extension-element-prefixes = NCNames\ exclude-result-prefixes = NCNames\ version = number>\ \</xsl:stylesheet> Таблица стилей XSLT должна как минимум объявлять пространство имен для XSL-преобразования. Версии XSLT должны соответствовать версии файла XML, что определяется требованиями внешней системы, принимающей данные. Обычно используется версия 1.0, но возможно использование и более свежих версий 2.0 или 3.0. \<xsl:stylesheet version="1.0"\ xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> Элемент \<xsl:template>:
Определяет повторно используемый шаблон для формирования желаемого вывода для узлов определенного типа в определенном контексте. \<xsl:template\ name= Qname\ match = Pattern\ priority = number\ mode = QName\ \</xsl:template>
ℹ️ Операторы xsl-template не могут быть вложенными. Если необходимо сформировать вывод родительского и дочерних узлов, то следует обрабатывать их отдельно (например, сначала родительский, потом дочерние).
Элемент \<xsl:strip-space>:
Удаляет состоящие из одних только пробелов текстовые узлы, которые могут находиться в элементах, указанных с помощью атрибутов elements. \<xsl:strip-space elements = tokens /> Элемент \<xsl:output>:
Задает параметры, используемые при сериализации результирующих деревьев. \<xsl:output\ | method = "xml" | "html" | "text" | QName \ |
version = nmtoken \
encoding = string\
| omit-xml-declaration = "yes" | "no"\ |
| --- | --- |
| standalone = "yes" | "no"\
doctype-public = string \
doctype-system = string \
cdata-section-elements = QNames \ |
| indent = "yes" | "no"\
media-type = string \
/>
Атрибуты:
-method — указывает общий метод, используемый для вывода дерева результатов. Если префикс отсутствует, атрибут задает метод, указанный в документе, который должен иметь одно из значений «xml», «html», «text» или квалифицированное имя (QName), не представляющее собой NCName. Если префикс присутствует, он расширяется и служит указанием на метод вывода.
-version — задает версию 1.0 по отношению к методу вывода «xml»; это значение появляется в XML-декларации вывода как \<?xml version="1.0"?>.
-encoding — задает предпочитаемую кодировку символов, которую должен использовать синтаксический анализатор для кодировки последовательностей символов в виде последовательностей байтов. Значение атрибута обрабатывается без учета регистра; оно должно содержать только печатаемые символы ASCII и быть зарегистрированным набором символов или начинаться с x-
-omit-xml-declaration — указывает, должен ли обработчик XSLT выводить XML-декларацию; значение должно быть yes или no.
-standalone — указывает, должен ли обработчик XSLT выводить объявление автономности документа; значение должно быть yes или no.
-doctype-public — задает общий идентификатор для использования в определении DTD.
-doctype-system — задает системный идентификатор для использования в определении DTD.
-cdata-section-elements — задает список квалифицированных имен Полные имена (XSLT) элементов, дочерние текстовые узлы которых нужно выводить с помощью разделов CDATA.
-indent — задает дополнительные пробелы, которые будут добавляться при выводе дерева результатов; значение должно быть yes или no.
-media-type — задает тип носителя (MIME-тип содержимого) данных, получающийся в результате вывода дерева результатов
Элемент \<xsl:copy>:
Cоздает копию текущего узла вне зависимости от его типа. Вместе с текущим узлом в выходящее дерево копируются только узлы пространств имен, ассоциированные с ним. Дочерние узлы и узлы атрибутов в выходящий документ не копируются.
\<xsl:copy\
use-attribute-sets = "наборы атрибутов">\
\<!-- Содержимое: шаблон -->\
\</xsl:copy>
Атрибуты:
-use-attribute-sets — необязательный атрибут, задает именованные наборы атрибутов.
Элемент \<xsl:apply-templates>:
Предписывает XSLT-процессору найти и применить соответствующий шаблон в зависимости от типа и контекста каждого выбранного узла.
\<xsl:apply-templates\
select = Expression\
mode = QName\
\</xsl:apply-templates>
Атрибуты:
-select — может использоваться для обработки узлов, выбранных с помощью выражения, вместо обработки всех узлов. Значением атрибута select является выражение Выражения (XSLT), результатом вычисления которого должен быть набор узлов. Выбранный набор узлов обрабатывается по порядку появления в документе, если не задан другой порядок сортировки.
-mode — атрибут mode позволяет обрабатывать элемент согласно его имени Полные имена (XSLT) несколько раз и каждый раз получать другой результат. Если элемент \<xsl:template> не имеет атрибута match, он не может иметь атрибута mode. Если элемент \<xsl:apply-templates> имеет атрибут mode, он применяется только к правилам шаблона из элементов \<xsl:template>, имеющих атрибут mode с тем же значением. Если у элемента \<xsl:apply-templates> нет атрибута mode, он применяется только к правилам шаблона из элементов \<xsl:template>, не имеющих атрибута mode.
Элемент \<xsl:attribute>:
Создает узел атрибута и присоединяет его к элементу вывода.
\<xsl:attribute\
name = "attribute-name" \
namespace = "uri-reference">\
\</xsl:attribute>
Атрибуты:
-name (обязательный) — имя создаваемого атрибута. Если это значение является полным именем (QName), узел атрибута создается в пространстве имен, привязанном в данный момент к префиксу, если это пространство не будет переопределено атрибутом namespace. Значение атрибута name интерпретируется как шаблон значения атрибута (выражения в фигурных скобках оцениваются и преобразуются в строки, как в элементе \<xsl:value-of>). Благодаря этому имя атрибута можно вычислить или получить из исходного XML-документа.
-namespace — URI пространства имен для создаваемого узла. Если атрибут name содержит имя QName, то указанный там префикс будет привязан к пространству имен, заданному атрибутом namespace. В результате при сериализации могут возникнуть дополнительные объявления пространств имен. Это значение интерпретируется как шаблон значения атрибута.
Элемент \<xsl:choose>:
Проводит проверку по нескольким условиям совместно с элементами \<xsl:otherwise> и \<xsl:when>.
Дочерние элементы \< xsl:otherwise>, \< xsl:when>.
Функция translate (XPath):
Возвращает первую строку аргумента, в которой символы из второй строки аргумента заменены на символы, находящиеся в той же позиции в третьей строке аргумента.
string translate(string, string, string) — функция обеспечивает сопоставление символов в первом аргументе. Второй и третий аргументы описывают схему сопоставления.
Пример:
при вызове функции translate("bar","abc","ABC") возвращается значение "BAr".
Элемент \<xsl:element>:
Создает выходной элемент с указанным именем.
\<xsl:element\
name = "element-name" \
namespace = "uri-reference"\
use-attribute-sets = QName\
\</xsl:element>
Атрибуты:
-name (обязательный) — имя создаваемого элемента. Если это значение является именем Полные имена (XSLT), то узел элемента создается в пространстве имен, которое в данный момент связано с этим префиксом, если иное не определено атрибутом namespace. Значение атрибута name интерпретируется как шаблон значения атрибута, иными словами, выражения в фигурных скобках вычисляются и преобразуются в строки, как в элементе \<xsl:value-of>. Это позволяет вычислить или получить из исходного кода XML имя элемента.
-namespace — URI пространства имен созданного элемента. Если атрибут name содержит имя QName, то указанный там префикс будет привязан к пространству имен, заданному атрибутом namespace. В этом случае при сериализации, возможно, потребуется объявлять дополнтельные пространства имен. Значение namespace интерпретируется как шаблон значения атрибута.
-use-attribute-sets — разделенный пробелами список наборов атрибутов, заданный как Полные имена (XSLT). Указание этого атрибута объявляет каждый атрибут в каждом перечисленном наборе атрибутов.
Элемент \<xsl:value-of>:
Вставляет значение выбранного узла в виде текста.
\<xsl:value-of\
select = Expression\ |
| disable-output-escaping = "yes" | "no" \ |
\</xsl:value-of>
Атрибуты: -select (обязательный) --- выражение. Выражение (XSLT) вычисляется в соответствии с текущим контекстом. Результаты преобразуются в строку, как если бы вызывалась функция string(). Набор узлов преобразуется в строку вставкой строкового значения первого узла множества. -disable-output-escaping — значение по умолчанию "no". Если указано значение "yes", то текстовый узел, сформированный элементом \<xsl:value-of>, будет выведен без escape-символов. Например, выражение \<xsl:value-of disable-output-escaping="yes" select="string(\'<\')"/> сформирует единственный символ "\<".
Пример XSLT-преобразований¶
Пример XSL файла
Описание
\<?xml version="1.0"?>\ \<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">\ \<xsl:strip-space elements="*" />\ \<xsl:output method="xml" version="1.0" encoding="UTF-8"
indent="yes" cdata-section-elements="ExtParam999Value"/>
"Шапка" документа.
Функция strip-space, указанная в шапке документа", убирает лишние пробелы во всем документе
\<xsl:template match="@*|node()">\ \<xsl:copy >\ \<xsl:apply-templates select="@*|node()"/>\ \</xsl:copy>\ \</xsl:template>
определение функции преобразования match. Использовать ее предпочтительнее, чем copy, поскольку при использовании match можно одновременно переназначить имя элемента, а при использовании copy имя элементв результирующем файле сохраняется то же, что и в исходном
\<xsl:template match="DocumentElement">\ \<Ads formatVersion="3" target="Avito.ru">\ \<xsl:apply-templates/>\ \</Ads>\ \</xsl:template>
поскольку операторы xsl-template не могут быть вложенными, сначала отдельно выполняется преобразование родительского узла Ads, а затем дочерних узлов Ad
\<xsl:template match="Objects_avito">\ \<Ad>\ \<xsl:apply-templates/>\ \</Ad>\ \</xsl:template>
\<xsl:template match="TaskID"> \</xsl:template>
\<xsl:template match="StateName"> \</xsl:template>
\<xsl:template match="ExtParam111Value"> \</xsl:template>
если основные или дополнительные параметры, возвращаемые SQL View, не нужны в результирующем файле, для них создаются "пустые" преобразования.
В данном примере не нужны ID задачи, название статуса и значение ДП с ID=111
\<xsl:template match="ExtParam222Value">\ \<CompanyName>\ \<xsl:apply-templates/>\ \</CompanyName>\ \</xsl:template>
\<xsl:template match="ExtParam333Value">\ \<Price>\ \<xsl:apply-templates/>\ \</Price>\ \</xsl:template>
ДП с ID=222 записывается в поле с именем CompanyName
ДП с ID=333 записывается в поле с именем Price
\<xsl:template match="ExtParam444Value">\ \<Floor>\ \<xsl:apply-templates select="@*|node()"/>\ \</Floor>\ \</xsl:template>
Рекурсивная обработка атрибутов, текста и элементов, пока не останется ни одного дочернего элемента
\<xsl:template match="CreatedTime">\ \<DateBegin>\<xsl:value-of select="substring-before(., \'T\')"/>\</DateBegin>\ \</xsl:template>
Обрезание вывода формата даты с YYYY-MM-DDThh:mm:ss до YYYY-MM-DD
\<xsl:template match="ExtParam555Value">\ \<xsl:choose>\ \<xsl:when test="//ExtParam555Value=\'Апартаменты\'">\ \<Category>Квартиры\</Category>\ \</xsl:when>\ \<xsl:otherwise>
\</xsl:otherwise>\ \</xsl:choose>\ \</xsl:template>
Условное преобразование:
значение ДП с ID=555 записывается в поле с именем Category. При этом если значение ДП равно "Апартаменты", то оно преобразуется в значение "Квартиры", иначе в поле Category не записывается ничего
\<xsl:template match="//url">\ \<xsl:element name="Image">\ \<xsl:attribute name="{name()}">\ \<xsl:value-of select="."/>\ \</xsl:attribute>\ \</xsl:element>\ \</xsl:template>
Поиск элемента "url", затем запись этого элемента в качестве атрибута в новый элемент "Image"