Главная -> XML&... -> XSLT в примерах 
>> Содержание << | Указатель

Введение

Страница 1 С XSL вы можете свободно модифицировать исходный текст. Так с помощью этого и этого преобразований можно получить различный результат из одного исходного файла.
Страница 2 Каждое преобразование XSL должно начинаться с элемента xsl:stylesheet. Атрибут version='1.0' определяет версию спецификации XSL. Этот пример представляет собой простейшее возможное преобразование. Поскольку оно не содержит чего-либо помимо заголовка, то используется обработка по умолчанию.
Страница 3 XSLT-процессоры анализируют исходный XML и пытаются найти подходящий XSL-шаблон. Если такой шаблон найден, то выполняются инструкции внутри него.
Страница 4 Содержание элементов может быть извлечено из исходного документа двумя основными способами. Это преобразование использует инструкцию xsl:value-of. В этом случае содержание элемента используется без какой-либо дальнейшей обработки. Инструкция xsl:apply-templates в этом преобразовании действует по-другому. Здесь XSLT-процессор продолжает обрабатывать выбранные элементы, для которых определен шаблон.

Шаблоны

Страница 5 XSLT-процессоры анализируют исходный XML и пытаются найти подходящий XSL-шаблон. Если такой шаблон найден, то выполняются инструкции внутри него.
Страница 6 Части XML-документа, к которым должен применяться шаблон, определяются путями адресации. Их синтаксис описан в Спецификации XPath. В простейших случаях он очень похож на адресацию файловой системы (это преобразование).
Страница 7 Обработка всегда начинается с шаблона, где match="/". Это значение пути адресации соответствует корневому узлу (в нашем случае source). Однако многие преобразования XSL не содержат такой шаблон явно. В этом случае используется неявный шаблон (он содержит только единственную инструкцию). Эта инструкция обозначает: обрабатывать все дочерние элементы текущего узла, включая текстовые узлы. Сравните это и это преобразования. Когда шаблон для узла существует, никакой обработки по умолчанию не происходит (это преобразование). Если вы хотите включить обработку потомков узла, то вы должны явно указать шаблоны для них (это преобразование).
Страница 8 Соответствие шаблонов определяется путями адресации, где конкретные пути разделяются с помощью символа "|" (это преобразование). Символ "*" обозначает все возможности. Сравните это и это преобразования.
Страница 9 "//" очень часто встречается в путях адресации. Когда он используется в начале пути адресации, он обозначает: выбрать все узлы определенного типа в документе (это преобразование). Внутри пути адресации он обозначает: выбрать все узлы, являющиеся потомками узла, указанного в первой части пути адресации (это преобразование).
Страница 10 С помощью режимов (modes) элемент может быть обработан многократно, причем каждый раз с различным результатом. В этом преобразовании один из режимов не существует.
Страница 11 Достаточно часто несколько шаблонов соответствует одному и тому же элементу в исходном XML. Поэтому надо решить, какой из них следует использовать. Для этого можно определить приоритеты с помощью атрибута priority. Если этот атрибут не определен, его приоритет вычисляется в соответствии с несколькими правилами. Это и это преобразования различаются приоритетами их шаблонов. Это преобразование показывает действие по умолчанию в отсутствие атрибутов priority. Шаблон CCC имеет меньший приоритет по сравнению с CCC/CCC, поскольку он менее специфичный. Сравните это и это преобразования. Шаблон CCC имеет меньший приоритет, чем CCC/CCC или AAA/CCC/CCC, хотя два последних имеют одинаковый приоритет. В таком случае XSLT-процессор может сообщить об ошибке. Если этого не произошло, XSLT-процессор должен выбрать среди соответствующих шаблонов тот, который будет последним в преобразовании. В этом преобразовании менее специфичный "*" имеет меньший приоритет по сравнению с CCC. Вычисленные приоритеты располагаются в диапозоне от -0.5 до 0.5. Более подробная информация содержится в Спецификации XSLT.

Атрибуты

Страница 12 К атрибутам можно обращаться также, как и к элементам. Надо только поставить "@" перед именем атрибута.
Страница 13 Атрибуты можно обрабатывать аналогично элементам.
Страница 14 Вы также можете выбирать элементы, которые содержат или не содержат данный атрибут. Это преобразование включает, а это преобразование исключает элементы, если определенный элемент присутствует.

Оси

Страница 15 Оси играют очень важную роль в XSLT. Для более подробной информации читайте XSLT reference. Сравните: ось child (это преобразование), ось descendant (это преобразование), ось parent (это преобразование), ось ancestor (это преобразование), ось following-sibling (это преобразование), ось preceding-sibling (это преобразование), ось following (это преобразование), ось preceding (это преобразование), ось attribute (это преобразование), ось namespace (это преобразование), ось self (это преобразование), ось descendant-or-self (это преобразование), ось ancestor-or-self (это преобразование).
Страница 16 В этом примере использовались все оси.
Страница 17 Ось child:: может быть опущена в пути адресации, так как она является осью по умолчанию. Ось attribute:: можно кратко записать в виде @. // является сокращением для /descendant-or-self::, . является синомимом для self::, а .. является сокращением для parent::.

Повторение и сортировка

Страница 18 Инструкция xsl:for-each определяет шаблон, который применяется для каждого узла, выбранного с помощью атрибута select.
Страница 19 Узлы, выбранные с помощью xsl:for-each (это и это преобразования) или xsl:apply-templates (это преобразование) можно отсортировать. Порядок сортировки определяется атрибутом order. В этом преобразовании проводится сортировка по возрастанию, а в этом — по убыванию.
Страница 20 В этом преобразовании сортировка проводится в текстовом режиме, а в этом — в числовом. Обратите внимание на важную деталь. В алфавите 2 идет после 1, поэтому в текстовом режиме 2 идет после 10.
Страница 21 В этом преобразовании при сортировке первыми идут символы верхнего регистра, а в этом — нижнего регистра.

Создание элементов и атрибутов

Страница 22 С помощью xsl:element в процессе обработки можно создавать новые элементы. В этом преобразовании используется эта возможность, в то время как в этом точно такой же результат достигается другим, более трудоемким способом.
Страница 23 Инструкция xsl:attribute также служит для генерирования элементов в процессе обработки. Она предназначена для создания атрибутов элемента, в который она заключена.
Страница 24 Инструкции copy и copy-of используются для копирования узлов в результирующее дерево. Инструкция copy копирует только текущий узел без дочерних элементов и атрибутов, в то время как copy-of — все.
Страница 25 Элемент xsl:copy может иметь атрибут use-attribute-sets. В этом случае можно определить атрибуты для копируемого элемента. Это преобразование не будет выполняться, как ожидалось (установка use-attribute-sets при помощи функции name), так как выражения в атрибутах, относящиеся к именованным XSLT-объектам не могут быть вычислены.

Условная обработка

Страница 26 Инструкция xsl:if позволяет реализовывать условные конструкции. Это преобразование демонстрирует типичный случай использования инструкции xsl:for-each, добавляя текст между отдельными компонентами. Однако, зачастую вы не захотите добавлять текст после последнего элемента. Здесь вам может помочь инструкция xsl-if (это преобразование).
Страница 27 Элемент xsl:choose используется для организации выбора между несколькими возможностями.
Страница 28 Как выяснить, что некоторый текст начинается с цифры.

Создание и форматирование чисел

Страница 29 Это преобразование демонстрирует поведение по умолчанию элемента xsl:number. Нумерация конкретных разделов зависит от позиции элемента chapter. Нумерация на каждом уровне идет независимо. Установка атрибута level равным значению "multiple" в этом преобразовании позволяет осуществить более естественную нумерацию.
Страница 30 xsl:number вставляет отформатированные числа в выходной поток. Формат задается с помощью атрибута format. Значение атрибута начинается с идентификатора формата, сопровождаемым символами разделителей. Изучите примеры, приведенные ниже, для сравнения нотации.
Страница 31 Это и это преобразования являются примерами форматирования многоуровневых числовых конструкций.

Переменные

Страница 32 В Этом и этом преобразованиях демонстрируются различные способы задания xsl:variable, а в этом и в этом преобразованияхxsl:param.
Страница 33 Преобразование может содержать несколько переменных с одинаковыми именами. В этом преобразовании демонстрируется способ, как возвращать значение глобальной переменной, которая имеет такое же имя, как и локальная. В этом преобразовании демонстрируется неверный вариант. Область видимости локальной переменной ограничивается элементом xsl:when. Поэтому в остальной части шаблона видима только глобальная переменная.
Страница 34 Параметры шаблону можно передать при помощи элемента xsl:with-param. Если шаблон содержит элемент xsl:param с таким же атрибутом name, что и xsl:with-param, то его значение будет использовано. Это преобразование является типичным примером. Если вы хотите передать переменную, то надо определить эту переменную при помощи элемента xsl:param. Примером неправильного подхода может служить это преобразование.
Страница 35 Переменная может в качестве своего значения держать фрагмент результирующего дерева. Операции, допустимые на фрагменте результирующего дерева, являются подмножеством допустимых на множестве узлов. Операции допустимы на фрагменте результирующего дерева только, если эти операции будут допустимыми над строкой (операция над строкой может сначала вызывать преобразование строки в число или булевую переменную). В частности, на фрагменте результирующего дерева нельзя использовать операторы "/", "//" и "[]". Когда допустимая операция выполняется на фрагменте результирующего дерева, она выполняется точно так, как она должна была быть выполнена на эквивалентном множестве узлов. Сравните это и это преобразования.
Страница 36 Есть тонкий момент при задании значения переменной.

Численные вычисления

Страница 37 Функция number явным образом конвертирует свой аргумент в число. Это преобразование является примером конвертации строк, а это преобразование — примером конвертации булевских переменных true и false.
Страница 38 Сложение, вычитание и умножение осуществляется обычным способом (это преобразование). Синтаксис для деления немного отличается от традиционного. Символ "/" зарезервирован для путей адресации и вместо него для обозначения деления используется ключевое слово div (это преобразование). Оператор mod возвращает остаток от деления нацело (это преобразование).
Страница 39 Функция sum() суммирует все числа из выбранного множества узлов. В этом преобразовании суммируются все числа, а в этом — только нечетные.
Страница 40 Функции ceilng(), floor() и round() преобразуют числа с плавающей запятой в целые определенным способом.
Страница 41 Функция string() преобразует свой аргумент к строковому типу. Эта функция обычно не используется явно в преобразованиях, так как в большинстве случаев она вызывается по умолчанию. Это преобразование является примером преобразования чисел к строковому типу. Обратите внимание на результат деления на 0.
Страница 42 Пример проверки на то, что тестовое значение является числом.

Булевые функции

Страница 43 В этом преобразовании строки являются аргументами функции boolean(). Строка является "истиной" тогда и только тогда, когда ее длина ненулевая. В этом преобразовании текст конвертируется в числовой тип, а затем передается в качестве аргументов функции boolean(). Это преобразование показывает разницу между тем, когда "0" является числом, и когда — строкой. В этом преобразовании в качестве аргумента функции boolean() используется подмножество узлов.
Страница 44 Функция not() возвращает "истину", если аргументом была "ложь", и "ложь" в противном случае.
Страница 45 Функции true() и false() обычно используются для проверки некоторых условий в процессе программирования.
Страница 46 Функция lang() возвращает "истину" или "ложь" в зависимости от того, совпадает ли язык контекстного узла с идентификатором языка, переданным ей в качестве параметра. Она действует следующим образом. Язык контекстного узла определяется значением атрибута xml:lang или, если не контекстный узел не имеет такого атрибута, значением атрибута xml:lang ближайшего предка контекстного узла. Если ни один из предков контекстного узла не имеет атрибута xml:lang, то функция lang() возвращает "ложь". Если же такой атрибут имеется, то функция lang() возвращает "истину", если значения атрибута и аргумента совпадают независимо от регистра символов, или значение атрибута имеет суффикс, начинающийся с символа "-", и его часть до суффикса совпадает со значением аргумента независимо от регистра символов.

Строковые функции

Страница 47 Функция string() преобразует свой аргумент к строковому типу. Эта функция обычно не используется явно в преобразованиях, так как в большинстве случаев она вызывается по умолчанию. Это преобразование является примером конвертации чисел в строковой тип. Обратите внимание на результат деления на 0.
Страница 48 Функция concat() возвращает конкатенацию своих аргументов.
Страница 49 Функция starts-with() принимает на вход два строковых аргумента и возвращает "истину", если первая строка начинается второй, и "ложь" в противном случае. Функция contains() также принимает на вход два строковых аргумента и возвращает "истину", если первая строка содержит вторую, и "ложь" в противном случае.
Страница 50 Функции substring-before() и substring-after() находят в первой строке вторую. Первая из них возвращает подстроку, которая ей предшествует, а вторая — подстроку, котороя за ней следует. Функция substring() возвращает подстроку переданного ей строкового аргумента, начинающуюся с позиции, определенной вторым аргументом, и длиной, определенной в третьем аргументе. Если третий аргумент опущен, то она возвращает подстрока продолжается до конца строки. Позицией первого символа является 1 (это преобразование). Это преобразование демонстрирует ситуацию, когда некоторые аргументы выходят за допустимый диапазон или не являются целыми. Возращаемая строка содержит те символы, для которых позиция больше или равна, чем значение второго аргумента и, если третий аргумент определен, меньше, чем сумма значений второго и третьего аргументов.
Страница 51 Функция string-length() возвращает количество символов в строке. Функция normalize-space() производит так называемую нормализацию строкового аргумента относительно пробелов. Она удаляет пробелы в начале и в конце строки, а все последовательности пробелов в теле строки заменяются одиночным пробелом.
Страница 52 Функция translate() возвращает строку из первого аргумента, в которой символы из второго строкового аргумента в соответствии с их позицией заменены на символы из третьего строкового аргумента. Если какой-либо символ встречается во втором аргументе более, чем один раз, то учитывается только первое его появление. Если строка из третьего аргумента длиннее, чем строка из второго аргумента, то остаток строки игнорируется.

Функции множеств узлов

Страница 53 Функция position() возвращает позицию контекста — число, равное порядковому номеру контекстного узла в обрабатываемом в данный момент множестве. Функция last() возвращает размер контекста — число, равное количеству узлов в обрабатываемом множестве. Это преобразование является демонстрацией использования этих функций в некоторых контекстах. В этом преобразовании демонстрируется действие этих функций на отсортированные и неотсортированные множества узлов внутри элемента xsl:for-each.
Страница 54 Функция count() возвращает количество узлов в множестве, переданном ей в качестве аргумента.
Страница 55 Функция id() позволяет обращаться к элементам по значениям их уникальных идентификаторов. Это преобразование является простым примером ее использования. Тщательно изучите это преобразование. Содержание элемента title не отображается внутри квадратных скобок, так как в DTD его атрибут id определен как CDATA, а не как ID. Одновременно можно обрабатывать несколько идентификаторов (это преобразование).
Страница 56 Пример использования функции id().
Страница 57 Функции name(), local-name() и namespace-uri() используются для получения информации имени элемента или атрибута и пространстве имен.

Вывод

Страница 58 Элемент xsl:output позволяет авторам преобразований определять, в каком виде должно быть представлено результирующее дерево. Если XSLT-процессор выводит результирующее дерево, то он должен делать это в точности так, как определено элементом xsl:output. Элемент xsl:output является элементом только верхнего уровня. В этом преобразовании используется метод вывода "html", а в этом — "xml". Сравните вывод пустых элементов.
Страница 59 Если элемент xml:output отсутствует, то по умолчанию методом вывода бедет "xml" (это преобразование), однако, если корневой элемент выходного документа имеет значение "html" (независимо от регистра символов), то методом вывода будет "html" (это преобразование).
Страница 60 Метод вывода "html" для пустых элементов, определенных спецификацией HTML, выводит тэги без косой черты после имени и закрывающих тэгов. Также при использовании этого метода вывода процессор не должен анализировать содержимое элементов script и style. Сравните с этим преобразованием. Для получения более подробной информации обратитесь к Спецификации XSLT.
Страница 61 Атрибут encoding определяет, какая кодировка предпочтительна для выходящего документа. Метод вывода "html" должен добавить непосредственно за открывающим тэгом элемента HEAD элемент META с определением используемой кодировки. Это преобразование использует для вывода кодировку UTF-8, это преобразование — UTF-16, а это — Cp1250.
Страница 62 Метод вывода "text" выводит результирующее дерево посредством вывода строковых значений каждого текстового узла в порядке следования в документе без каких-либо изменений.

Копирование

Страница 63 Инструкции copy и copy-of используются для копирования узлов в результирующее дерево. Инструкция copy копирует только текущий узел без дочерних элементов и атрибутов, в то время как copy-of — все.
Страница 64 Элемент xsl:copy может иметь атрибут use-attribute-sets. В этом случае можно определить атрибуты для копируемого элемента. Это преобразование не будет выполняться, как ожидалось (установка use-attribute-sets при помощи функции name), так как выражения в атрибутах, относящиеся к именованным XSLT-объектам не могут быть вычислены.

Дополнительные функции

Страница 65 Функция current() возвращает множество, состоящее только из текущего узла преобразования. Для наиболее удаленых выражений (выражений, не встречающихся внутри других выражений), текущий узел всегда совпадает с узлом контекста. Однако, внутри квадратных скобок обычно они являются двумя различными узлами.
Страница 66 Функция generate-id() используется для создания уникального идентификатора, отвечающего Спецификации XML. Это преобразование использует эту функцию для добавления идентификатора ко всем элементам исходного XML.

Комбинирование преобразований

Страница 67 В преобразование можно импортировать (xsl:import) и включать (xsl:include) внешните файлы преобразований. Импортирование почти полностью аналогично включению за исключением того, что определения и шаблоны в основном файле имеют превосходство над шаблонами и определениями в импортируемых файлах. Это и это преобразования импортируются или включаются в остальные.
Страница 68 В это преобразование включается это, в которое, в свою очередь, импортируется это преобразование.
Страница 69 Другие примеры использования xsl:include и xsl:import.
Страница 70 Вы можете использовать элемент xsl:apply-imports для использования импортированных шаблонов, чье поведение, однако, вы можете изменить. В это преобразование импортируется это, а его шаблоны аннулируются. Это преобразование импортирует это и изменяет его шаблоны. Инструкция xsl:apply-imports работает только для шаблонов импортированных с помощью xsl:import, а не включенных с помощью xsl:include (это преобразование).
Страница 71 Превосходство при импорте сильней, чем превосходство приоритета. Смотрите это преобразование.