'

Языки описания информации

Понравилась презентация – покажи это...





Слайд 0

Языки описания информации Лекция 4. Кафедра «ОСУ» Весенний семестр 2010/2011 уч. года XSLT


Слайд 1

Язык XSLT (расширяемый язык преобразований, XSL таблицы стилей) (eXtensible Stylesheet Language Transformations)


Слайд 2

Язык таблиц разметки – XSL (eXtensible Stylesheet Language) это набор стандартов организации W3C, описывающих языки преобразования и визуализации XML-документов. Основными частями данного языка являются: язык преобразований XML-документов – XSL Transformations (XSLT); язык разметки типографских макетов и иных предпечатных материалов – XSL Formatting Objects (XSL-FO).


Слайд 3

Язык XSL-FO XSL Formatting Objects (XSL-FO) - язык разметки типографских макетов и иных предпечатных материалов. Документ на языке XSL-FO (XSL Formatting Objects) представляет собой XML файл, в котором хранятся данные для печати или вывода на экран (например, просто текст). Эти данные находятся внутри специальных тэгов fo:block, fo:table, fo:simple-page-master и д.р., с помощью которых задаются отступы, переводы строк и т.д. Общая идея использования XSL состоит в следующем вначале пользователь создаёт документ в виде обычного XML документа (а не в виде форматированного объекта XSL-FO). затем применяется XSLT-преобразование, которое формирует XML документ на языке XSL-FO. Полученный XSL-FO документ передаётся приложению (FO-процессор), который конвертирует XSL-FO-документ в какой-либо читаемый и/или печатаемый формат. Наиболее часто используется преобразование в PDF или RTF-файлы, либо просто выполняется отображение документа в окне программы.


Слайд 4

Пример XSL-FO документа <?xml version="1.0" encoding="iso-8859-1"?> <fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format"> <fo:layout-master-set> <fo:simple-page-master master-name="my-page"> <fo:region-body margin="1in"/> </fo:simple-page-master> </fo:layout-master-set> <fo:page-sequence master-reference="my-page"> <fo:flow flow-name="xsl-region-body"> <fo:block>Hello, world!</fo:block> </fo:flow> </fo:page-sequence> </fo:root>


Слайд 5

Язык XSLT С помощью языка XSLT можно преобразовать XML-документ в любой другой XML документ, например, HTML, WML или RTF. Для обработки XML документа c помощью XSLT, необходимо в него включить следующую инструкцию:   <?xml-stylesheet type="text/xsl" href="my-style.xsl"?>   Самым доступным XSLT-процессором на данный момент для Microsoft Windows является MSXML (поставляется с Internet Explorer начиная с версии 4.5 и выше); для систем на основе GNU — xsltproc.


Слайд 6

Преобразование XML документа


Слайд 7

Использование XSLT преобразования


Слайд 8

Использование XSLT на промежуточном уровне ПО


Слайд 9


Слайд 10


Слайд 11


Слайд 12


Слайд 13

Как XSLT работает


Слайд 14

XSLT in POP


Слайд 15

XSLT in MOM


Слайд 16


Слайд 17


Слайд 18

Выходной синтаксис для XSLT XSLT может создать результат с использованием трех выходных синтаксисов XML файлы HTML файлы Text (не размеченные тэгами файлы) ASCII email message comma-separated file desktop publishing system format (e.g., XTags for QuarkXPress)


Слайд 19

Назначение XSLT XSLT was designed to process XML Takes full advantage of the tree XML constructs are built in ( no special programming) Solves problems with order of the material document model/processing mismatch interchange (mine different from yours different from ours) personalization/localization Part of the XML family, so applications built to support Makes content fluid, as XML and SGML have always promised


Слайд 20

Что может делать XSLT Извлечь что-либо из входного документа. Изменить последовательность элементов (rearrange / sort) Удалить что-либо из входного документа. Использовать один и тот же элемент или атрибут многократно. Добавить сгенерированный текст.


Слайд 21

XSLT легко преобразует XML документ в разные XML форматы Переименовать элемент или атрибут. Изменить элемент xxx в элемент yyy Преобразовать элементы в атрибуты. Преобразовать атрибуты в элементы.


Слайд 22

XSLT хорошо работает с размеченными документами XSLT работает лучше всего, когда Требуется получить размеченный тэгами результат! Иерархия задается явно . Наиболее важными отношениями являются древовидные отношения включение (parent / child) siblings attributes


Слайд 23

XSLT не подходит для любых преобразований Совершенно не подходит Для преобразования произвольных документов в XML формат. Для обработки не XML данных (Word, QuarkXPress, SGML). Не так эффективен, как большинство универсальных языков программирования для: обработки чисел (arithmetic and higher math) обработки строк (parsing) обработки очень больших файлов создания структуры там, где ее не было (преобразование плоского файла в иерархию).


Слайд 24

XSLT имеет слабые возможности работы с текстом (строками) An XSLT processor expects to work on a tree of nodes not an XML file of tags and text If you have untagged files (comma delimited, space delimited, tab delimited) there is no tree strings must be “parsed” into pieces XSLT does this awkwardly (XSLT 2.0 has better string manipulation than XSLT 1.0, but…)


Слайд 25

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


Слайд 26

Язык XSLT XSLT это декларативны язык описания преобразований структуры XML документов. XSLT документы называются XSL-таблица стилей или XSLT трансформациями. Каждая XSL-таблица стилей должна иметь корневой элемент, представленный ниже. <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <!-- один или несколько элементов шаблона …--> </xsl:stylesheet> Первым атрибут элемента stylesheet задает версию XSLT, Второй атрибут xmlns:xsl задает пространство имен для элементов языка XSLT. В соответствии с этим тэгом все XSL-элементы принадлежат пространству имен, заданным префиксом «xsl» (т. е. перед XSL элементами пишется префикс «xsl:».


Слайд 27

Как процессор XSL трансформирует исходный документ Язык XSLT работает не с синтаксисом документа, а с его моделью: Исходный формат и создаваемый формат являются приложениями XML и подлежащая структура в обоих случаях представляет собой дерево. Таблица стилей XSL — это документ XML, и потому она также может быть представлена в виде дерева. Процессоры XSLT работают с тремя деревьями.


Слайд 28

Язык XSLT является декларативным, т.е. в таблице стилей описывается: как должен выглядеть результат, а не то, как он должен быть трансформирован; именно для выполнения этой работы нужен процессор XSL. Таблица стилей XSL состоит из шаблонов (templates), описывающих, как некоторый узел исходного дерева должен быть представлен в дереве результата. Процессор проходит по дереву источника, начиная с корня, и ищет соответствующие шаблоны в дереве таблицы стилей. Обнаружив шаблон, он с помощью содержащихся в нем правил записывает абстрактное представление результата в дерево результата. Так он перемещается по документу узел за узлом (это определяется инструкцией XSLT <xsl:apply-template>) и ищет соответствия в таблице стилей.


Слайд 29

Если соответствующего шаблона не обнаруживается, он переходит к следующему. Можно сказать, что в таком случае он выполняет шаблон по умолчанию, который не приводит к результату на выходе. По завершении работы процессора дерево результата можно представить в виде XML документ, HTML документа, текста, или в другой желаемой форме. Теоретически события должны происходить в описанной последовательности. Однако в методах создания обработчиков XSLT используются различные вариации.


Слайд 30

Конструктор последовательности Конструктор последовательности это набор (последовательность) дочерних (sibling) узлов в трансформации (stylesheet), которые могут быть обработаны (evaluated), чтобы вернуть последовательность узлов или атомарных значений. Способ использования полученной последовательности зависит от содержащейся инструкции. [Definition: A sequence constructor is a sequence of zero or more sibling nodes in the stylesheet that can be evaluated to return a sequence of nodes and atomic values. The way that the resulting sequence is used depends on the containing instruction.]


Слайд 31

Элементы языка XSLT В языке XSLT определено около полусотни элементов. Элементы верхнего уровня (17 элементов) (или декларации), которые могут включаться в корневой элемент «xsl:stylesheet» К таким элементам относятся: xsl: import, xsl: include, xsl: attribute-set, xsl:character-map, xsl:date-format, xsl:decimal-format, xsl:function, xsl:import-schema, xsl:key, xsl:namespace-alias, xsl:output, xsl:param, xsl:preserve-space, xsl:sort-key, xsl:strip-space, xsl:template, xsl:variable. Кроме xsl:param и xsl: variable все другие элементы верхнего уровня могут включаться только непосредственно в к корневой элемент «xsl:stylesheet». Другие элементы (более 30) - могут записываться в теле элементов верхнего уровня. Наиболее часто используемыми элементами являются: xsl:apply-templates, xsl:value-of, xsl:copy-of, xsl:sort, xsl:text. Все элементы являются необязательными и могут располагаться в любом порядке, за одним исключением: декларации xsl:import, (если они есть) должны быть записаны первыми.


Слайд 32

Инструкции Формально инструкции XSLT определяются как элементы, которые можно вставлять в конструктор последовательности. Инструкции являются элементами не верхнего уровня вложенности. К инструкциям относятся следующие элементы элементы, создающие узлы всех семи видов и последовательности узлов: xsl:element, xsl:attribute, xsl:text, xsl:comment, xsl:processing-instruction, xsl:namespace, xsl:result-document, xsl:sequence. элементы xsl:apply-templates, xsl:value-of, xsl: variable и др. (всего более двадцати элементов). элементы, определяющие правила выбора преобразования: xsl:if, xsl:for-each, xsl:choose, элементы, копирующие узлы xsl:copy, xsl:copy-of.


Слайд 33

Инструкция 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 />


Слайд 34

Декларация xsl:import Элемент xsl:import записывается очень просто: <хsl:import href="адрес URI таблицы стилей" /> Его можно записать только непосредственно в корневом элементе xsl:stylesheet и только в самом начале таблицы стилей. Элементов xsl: import может быть несколько. Процессор XSLT отыскивает таблицу стилей по указанному атрибутом href адресу и подставляет ее на место элемента xsl:import перед преобразованием. Некоторые правила преобразования из таблиц, импортируемых элементами xsl:import, могут конфликтовать с правилами, импортированными из других таблиц или определенными в самой таблице стилей. В таком случае чаще всего применяются те правила, которые записаны последними. Поэтому порядок записи элементов xsl:import в таблицу стилей имеет большое значение.


Слайд 35

Декларация xsl:include Элемент xsl:include также включает внешние таблицы стилей в текущую таблицу. Он записывается точно так же, как элемент xsl:import, и оказывает такое же действие: <xsl:include href="адрес URI таблицы стилей" /> Его можно записать в любом месте таблицы стилей (в отличие от элемента xsl:import, который можно записывать только непосредственно в корневом элементе xsl:stylesheet). В отличие от элемента xsl:import порядок записи элементов xsl:include в таблице стилей не имеет значения.


Слайд 36

Шаблон (pattern) Прежде чем сделать преобразование дерева документа XML, из него следует выбрать те узлы, которые подвергнутся тому или иному преобразованию. Их можно выбирать по некоторому образцу (XPath выражению), который может содержать имени элементов, имена атрибутов содержимое атрибутам другие признаки. Условия отбора узлов задаются образцом (pattern), записанным в виде одного или нескольких выражений языка XPath 2.0. Выражения, содержащиеся в образце, объединяются вертикальной чертой |, означающей, что выбираемый узел должен удовлетворять хотя бы одному выражению образца.


Слайд 37

Декларация xsl:template Шаблоны описываются с помощью элемента xsl:template, который содержит: не обязательный атрибут «match» в котором задается XPath маршрут поиска (XPath выражение, образец) для отбора узлов, подлежащих преобразованию, не обязательный атрибут «name», в котором определяется имя шаблона. тело содержит конструктор последовательности узлов и атомарных значений, которая и будет результатом преобразования отобранных по образцу узлов. Например <xsl: template match="Образец" name="Имя"> Конструктор </хsl:template>


Слайд 38

Атрибуты xsl:template Каждый из атрибутов «match» и «name» не обязателен, но хотя бы один из них должен присутствовать. Шаблон можно вызвать по имени элементом «xsl:call-template», а если он не содержит атрибута «match», то такой вызов обязателен, поскольку неизвестны узлы, к которым его надо применить, и он не будут применяться автоматически. Очень часто именованный шаблон содержит параметры, заданные элементами «xsl:param», и вызывается с различным параметрами совсем как обычная функция.


Слайд 39

У элемента xsl: template могут быть дополнительные атрибуты «mode», «as», «priority»: атрибут «mode» определяет режим обработки. атрибут «as» указывает желаемый тип результата (полученная последовательность будет приведена к этому типу). атрибут «priority» назначает правилу приоритет, который будет учитываться при отборе правил, применимых к некоторому узлу. При вызове именованного шаблона элементов xsl:call-template атрибуты match, mode и priority не используются (игнорируются). Если у именованного шаблона нет атрибута «match», то у него не должно быть и атрибутов “mode” и “priority”, в них просто нет никакого смысла.


Слайд 40

В образце можно записать не всякое выражение XPath, а только путь, каждый шаг которого определяется осью, причем допускаются только три оси: child (по умолчанию), // и attribute. Это означает, что, находясь в каком-то узле, можно "видеть", кроме него самого, только его атрибуты и узлы-потомки. Обратите внимание на то, что явная запись оси descendant-or-self недопустима, применяется только сокращенная запись //. Запись оси attribute:: можно сократить до одной "собачки" @. Текущий узел очень часто обозначается точкой.


Слайд 41

Каждое XSLT-преобразование должна содержать один и только один шаблон с атрибутом match, который имеет значение "/".


Слайд 42

Хотя образец и строится как выражение языка XPath, но его цель — не отобрать последовательность узлов, а проверить соответствие узла данному образцу. Узел Node соответствует образцу (pattern) тогда и только тогда, когда узел Node принадлежит последовательности узлов -результату вычисления выражения //Pattern. Например, образцу person//street будут соответствовать все узлы из последовательности //person//street, а именно все узлы street, вложенные в узлы-элементы person даже через несколько промежуточных узлов. Перечисленные ограничения касаются только образцов. В других конструкциях языка XSLT можно применять выражения XPath в полном объеме.


Слайд 43

XSLT копирующее входной документ в выходной Если таблица стилей состоит из единственного правила, предназначенного для обработки корневого узла, в результате просто копируется всё содержимое шаблона, а XSLT-инструкции (элементы 'xsl:…') заменяются вычисляемым содержимым. XSLT предлагает даже специальный формат («literal result element as stylesheet») для таких простых, одношаблонных трансформаций. XSLT по умолчанию в XML-редакторе VS 2010 <?xml version="1.0" encoding="utf-8"?> <xsl:stylesheet version="1.0" xmlns:xsl=http://www.w3.org/1999/XSL/Transform xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl"> <xsl:output method="xml" indent="yes"/> <xsl:template match="@* | node()"> <xsl:copy> <xsl:apply-templates select="@* | node()"/> </xsl:copy> </xsl:template> </xsl:stylesheet>


Слайд 44

Инструкция xsl:apply-templates Элемент xsl:apply-templates указывает XSLT процессору найти для применения подходящий шаблон, на основе типа и контекста, каждого выбранного узла. Элемент xsl:apply-templates, записываемый чаще всего внутри элемента xsl: template, в простейшем виде пуст: <xsl:apply-templates /> Он предписывает обработать рекурсивно все узлы-потомки узлов, отобранных родительским элементом xsl:template.


Слайд 45

Атрибуты элемента «xsl:apply-templates» У элемента xsl:apply-templates есть необязательные атрибуты «select» и «mode». атрибут select, в котором задается выражение, дающее последовательность узлов. Если атрибут «select» задан, то список узлов формируется на основе указанного запроса XPath. В противном случае список содержит все дочерние узлы. атрибут mode выбирает режим обработки из режимов, уже определенных в элементах xsl:template. Режим — это любое имя, но два режима предопределены. текущий режим, отмечаемый словом #current, и режим по умолчанию, принимаемый при отсутствии атрибута mode, или отмечаемый явно словом #default. Содержимым элемента xsl: apply-templates могут служить элементы xsl:sort и xsl:with-param.


Слайд 46

Встроенные шаблоны (правила) Встроенные шаблоны (правила) выполняют обход дерева входного документа (depth-first обход) и переписывают в выходной документ содержание всех встречающихся текстовых узлов и атрибутов. Встроенные шаблоны включают следующие три правила: для текущего узла или корневого узла вызвать шаблоны, которые подходят для его дочерних узлов: <xsl:template match="* | /"> <xsl:apply-templates /> </xsl:template> если текущий узел является текстовым узлом или атрибутом, то его значение переносится в результирующий документ: <xsl:template match="text() | @*"> <xsl:value-of select="." /> </xsl:template> если текущий узел является инструкцией для XML процессора или комментарием, то ничего не делается: <xsl:template match="processing-instruction() | comment()" />


Слайд 47

Шаблонное правило по умолчанию для узлов элементов и корневого узла Самое важное шаблонное правило гарантирует обработку дочерних элементов. Правило выглядит следующим образом: <xsl:template match="*|/"> <xsl:apply-templates/> </xsl:template>  Символ «звездочка» (*) является подстановочным выражением XPath, соответствующим всем узлам элементов, независимо от имени и пространства имен, к которому они относятся. Но звездочка не соответствует атрибутам, текстовым узлам, комментариям или узлам инструкций обработки. Косая черта (/) – это выражение XPath, соответствующее корневому узлу, который выбирается для обработки первым, следовательно, и этот шаблон процессор исполняет первым (если только не существует другого шаблона, отличного от встроенного, который также соответствовал бы корневому узлу).


Слайд 48

Если рассматривать данное правило изолированно, оно означает, что XSLT в итоге находит и применяет шаблоны ко всем узлам, кроме узлов атрибутов и пространств имен так как любой узел, кроме узлом атрибутов или пространств имен, является корневым узлом или его наследником (дочерним узлом корневого узла или дочерним узлом элемента). Только узлы атрибутов и пространств имен не являются дочерними узлами своих родителей (их можно рассматривать как узлы, «лишенные наследства»). Конечно, конкретные шаблоны могут переопределить это встроенное правило. Например, когда в таблицу преобразований включен шаблон, соответствующий элементам person, дочерние элементы person не обязательно будут обрабатываться, если только особый шаблон не укажет на необходимость их обработки.


Слайд 49

Шаблонное правило по умолчанию для текстовых узлов и узлов атрибутов Самое основное из встроенных шаблонных правил копирует значение текстовых узлов и узлов атрибутов в выходной документ. Это выглядит следующим образом: <xsl:template match="text()|@*"> <xsl:value-of select="."/> </xsl:template>   Функция text() – это выражение XPath, соответствующее всем текстовым узлам, аналогично тому, как first_name является выражением XPath, соответствующим всем узлам элементов first_name. @* – это выражение XPath, соответствующее всем узлам атрибутов. Вертикальная черта объединяет эти два выражения, выбирая и текстовые узлы и узлы атрибутов. Содержимое этого шаблона говорит о том, что при обнаружении текстового узла или узла атрибута процессор должен вывести значение этого узла. Для текстового узла это значение равно просто его тексту. Для атрибута значение равно значению атрибута узла, но не его имени.


Слайд 50

Шаблон по умолчанию для узлов комментариев и узлов инструкций обработки Встроенное шаблонное правило для комментариев и инструкций обработки выглядит следующим образом: <xsl:template match="processing-instruction()|comment()"/>  Это правило относится ко всем комментариям и инструкциям обработки. Оно ничего не выводит в дерево результата. Если не предоставить конкретных правил для комментариев и инструкций обработки, никакие части этих узлов не будут скопированы из входного документа в выходной.


Слайд 51

Инструкция xsl:value-of Элемент value-of добавляет текстовое содержимое заданного XML-элемента – а также любых его дочерних элементов, которые он имеет – в выходной XML документ. Заданный XML-элемент указывается заданием образца, который присваиваете атрибуту «select» XSL-элемента value-of. Элемент «xsl:value-of» вычисляет выражение, записанное в его обязательном атрибуте select, и преобразует его в строку. Например, чтобы для ранее определенного объекта var2, получить значение надо записать: <xsl:value-of select="$var2" /> Если в результате вычисления выражения получается последовательность, то процессор XSLT выберет из нее только первый элемент, преобразованный в строку.


Слайд 52

На рисунке показано как браузер генерирует первую часть блока HTML-разметки для документа и таблицы стилей.


Слайд 53

Порядок работы XSLT процессора


Слайд 54

Подготовка к трансформации Прочитать таблицу стилей XSLT с помощью XML-парсера и перевести его содержимое в дерево узлов (дерево таблицы стилей), согласно модели данных XPath. Прочитать входные данные XML с помощью XML-парсера перевести его содержимое в дерево узлов (исходное дерево), согласно модели данных XPath. К XSLT-дереву добавляются три правила, которые задают поведение по умолчанию для любых типов узлов, которые могут быть встречены при обработке: Для текущего и корневого узла задаётся инструкцию обработки их потомков. Для всех текстовых узлов или узлов атрибутов задается инструкция сделать копию их содержимого в результирующее дерево. Для всех узлов комментария и узлов-инструкций обработки задается правило их обработку. Шаблоны, явно заданные в XSLT, могут перекрывать часть или все шаблоны-правила, заданные по умолчанию. Если шаблон не содержит явных правил, встроенные правила будут применены для рекурсивного обхода исходного дерева и только текстовые узлы будут скопированы в результирующее дерево (узлы атрибутов не будут достигнуты, так как они не являются «детьми» их родительских узлов). Полученный таким образом результат является просто конкатенацией всех текстовых фрагментов из исходного XML-документа.


Слайд 55

Последовательность работы процессора XSLT Строится дерево, являющуюся внутренним представлением XML документа. Создается структура для XSLT документа (это может быть также дерево или структура любого типа, оптимизированная для обработки шаблонов и соответствия образцов). Выбирается корневой элемент входного документа (оно становится контекстным). Каждый раз, встретив элемент типа <xsl:apply-templates>, процессор формируется список узлов и работа продолжается с этим списком. Если элемент <xsl:apply-templates> содержит атрибут «select», список узлов формируется на основе указанного запроса XPath. В противном случае список содержит все дочерние узлы. Каждый раз, встретив элемент типа <xsl:value-of>, процессор извлекает значение из исходного дерева, основываясь на выражении XPath его атрибута select. Трансформация не ограничивается только трансляцией типа один-к-одному: она позволяет добавлять новое информационное содержание, добавлять и удалять элементы, а также осуществлять преобразование типа один-ко-многим.


Слайд 56

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


Слайд 57

Порядок обработки текущего узла Поиск наиболее подходящего шаблона правила. Выполняется проверка соответствия шаблона (который является выражением XPath) для каждого правила, указывая узлы, для которых правило может быть применено. XSLT процессор назначает каждому шаблону относительный приоритет и старшинство для облегчения разрешения конфликтов. Порядок шаблонных правил в таблице стилей также может помочь разрешению конфликтов между шаблонами, которые соответствуют одинаковым узлам, но это не оказывает влияния на порядок, в котором узлы будут обрабатываться. Выполнение содержания правил шаблона . Не XSLT-элементы и текстовые узлы, обнаруженные в правиле, копируются, «дословно», в результирующее дерево. Комментарии и управляющие инструкции игнорируются. XSLT элементы рассматриваются, как инструкции и имеют специальную семантику, которая указывает на то, как они должны интерпретироваться. Одни XSLT элементы предназначены для добавления узлов в результирующее дерево, другие XSLT элементы являются управляющими конструкциями. Обработка инструкции xsl:apply-templates приводит к выборке и обработке нового набора узлов. Узлы идентифицируются с помощью выражения XPath. Все узлы обрабатываются в том порядке, в котором они содержатся в исходном документе.


Слайд 58

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


Слайд 59

Пример XSLT трансформации


Слайд 60

Пример преобразования XML документа <?xml version="1.0"?> <!-- File name: XslDemo01.xml --> <?xml-stylesheet type="text/xsl" href="XslDemo01.xsl"?> <BOOK> <TITLE>Moby-Dick</TITLE> <AUTHOR> <FIRSTNAME>Herman</FIRSTNAME> <LASTNAME>Melville</LASTNAME> </AUTHOR> <BINDING>hardcover</BINDING> <PAGES>724</PAGES> <PRICE>$9.95</PRICE> </BOOK> <?xml version="1.0"?> <!-- File name: XslDemo01.xsl --> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:template match="/"> <H2>Book Description</H2> <SPAN STYLE="font-style:italic">Author: </SPAN> <xsl:value-of select="BOOK/AUTHOR"/><BR/> <SPAN STYLE="font-style:italic">Title: </SPAN> <xsl:value-of select="BOOK/TITLE"/><BR/> <SPAN STYLE="font-style:italic">Price: </SPAN> <xsl:value-of select="BOOK/PRICE"/><BR/> <SPAN STYLE="font-style:italic">Binding type: </SPAN> <xsl:value-of select="BOOK/BINDING"/><BR/> <SPAN STYLE="font-style:italic">Number of pages: </SPAN> <xsl:value-of select="BOOK/PAGES"/> </xsl:template> </xsl:stylesheet>


Слайд 61


Слайд 62

Использование нескольких шаблонов Другой способ отображения повторяющихся XML-элементов состоит в создании отдельного шаблона для каждого элемента с последующим вызовом этого шаблона с использованием XSL-элемента apply-templates. Например: <?xml version="1.0"?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:template match="/"> <H2>Book Inventory</H2> <xsl:apply-templates select="INVENTORY/BOOK" /> </xsl:template> <xsl:template match="BOOK"> <SPAN STYLE="font-style:italic">Title: </SPAN> <xsl:value-of select="TITLE"/><BR/> <SPAN STYLE="font-style:italic">Author: </SPAN> <xsl:value-of select="AUTHOR"/><BR/> <SPAN STYLE="font-style:italic">Binding type: </SPAN> <xsl:value-of select="BINDING"/><BR/> <SPAN STYLE="font-style:italic">Number of pages: </SPAN> <xsl:value-of select="PAGES"/><BR/> <SPAN STYLE="font-style:italic">Price: </SPAN> <xsl:value-of select="PRICE"/><P/> </xsl:template> </xsl:stylesheet>


Слайд 63

В данном примере таблицы преобразования содержится два шаблона. Один шаблон содержит инструкции для отображения всего документа (путем установки match="/", указывающей на корневую часть документа). Все XSL-таблицы стилей требуют наличия такого шаблона. Другой шаблон содержит инструкции для отображения элемента BOOK (шаблон с установкой match="BOOK"). Сначала браузер обрабатывает шаблон, соответствующий корневой части элемента: <xsl:template match="/"> <H2>Book Inventory</H2> <xsl:apply-templates select="INVENTORY/BOOK" /> </xsl:template> XSL-элемент apply-templates сообщает браузеру, что для каждого элемента BOOK внутри корневого элемента INVENTORY он должен обрабатывать шаблон, отвечающий элементу BOOK – т. е. шаблон, для атрибута match которого установлено значение "BOOK".


Слайд 64

Таблица стилей включает следующий шаблон, отвечающий элементу BOOK: <xsl:template match="BOOK"> <SPAN STYLE="font-style:italic">Title: </SPAN> <xsl:value-of select="TITLE"/><BR/> <SPAN STYLE="font-style:italic">Author: </SPAN> <xsl:value-of select="AUTHOR"/><BR/> <SPAN STYLE="font-style:italic">Binding type: </SPAN> <xsl:value-of select="BINDING"/><BR/> <SPAN STYLE="font-style:italic">Number of pages: </SPAN> <xsl:value-of select="PAGES"/><BR/> <SPAN STYLE="font-style:italic">Price: </SPAN> <xsl:value-of select="PRICE"/><P/> </xsl:template> Поскольку этот шаблон отвечает элементу BOOK, элемент BOOK является текущим элементом в контексте шаблона. В связи с этим доступ к дочерним элементам BOOK осуществляется посредством образца, содержащего только имя элемента, как в нашем примере: <xsl:value-of select="TITLE"/>


Слайд 65

Пример простого XML документа <?xml version="1.0"?> <people xmlns="http://namespaces.oreilly.com/people"> <person born="1912" died="1954"> <name> <first_name>Алан</first_name> <last_name>Тьюринг</last_name> </name> <profession>специалист по информатике</profession> <profession>математик</profession> <profession>криптограф</profession> </person> <person born="1918" died="1988"> <name> <first_name>Ричард</first_name> <middle_initial>Ф</middle_initial> <last_name>Фейнман</last_name> </name> <profession>физик</profession> <hobby>Игра на бонгах</hobby> </person> </people>


Слайд 66

Результат обработки вcтроенными правилами (пустое XSLT) <?xml version="1.0" encoding="utf-8"?> Алан Тьюринг специалист по информатике математик криптограф Ричард Ф Фейнман физик Игра на бонгах


Слайд 67

Именованные шаблоны Именованный шаблон это шаблон, котором задан атрибут «name». Он принимает переданные параметры с помощью инструкции «xsl:param». Например: <xsl:template name="print"> <xsl:param name="message"/> <!-- template content goes here --> </xsl:template> Вызов на выполнение именованного шаблона выполняется с помощью инструкции xsl:call-template (вместо использования инструкции xsl:apply-templates). Например: <xsl:call-template name="print"> <xsl:with-param name="message" select="'See if it prints this message.'"/> </xsl:call-template>


Слайд 68

Режимы Иногда одно и то же содержимое из входного документа должно появиться в выходном документе несколько раз, каждый раз отформатированное в соответствии с разными шаблонами. Например, заголовки глав книги могут форматироваться в одном стиле в самих главах и в другом – в оглавлении книги. Оба элемента – xsl:apply-templates и xsl:template – могут иметь необязательный атрибут «mode», ставящий разные шаблоны в соответствие разным применениям. Атрибут mode элемента xsl:template указывает, в каком режиме следует активизировать этот шаблон. Элемент xsl:apply-templates с атрибутом mode активизирует только шаблоны с соответствующими атрибутами mode.


Слайд 69

Таблица стилей, использующая режимы <?xml version="1.0"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:template match="people"> <html> <head><title>Знаменитые ученые</title></head> <body> <ul><xsl:apply-templates select="person" mode="toc"/></ul> <xsl:apply-templates select="person"/> </body> </html> </xsl:template> <!-- Шаблоны режима оглавления --> <xsl:template match="person" mode="toc"> <xsl:apply-templates select="name" mode="toc"/> </xsl:template> <xsl:template match="name" mode="toc"> <li><xsl:value-of select="last_name"/>, <xsl:value-of select="first_name"/></li> </xsl:template> <!-- Шаблоны обычного режима --> <xsl:template match="person"> <p><xsl:apply-templates/></p> </xsl:template> </xsl:stylesheet>


Слайд 70

Пример использования шаблонов в таблице стилей, начинающей выходной документ со списка имен. <?xml version="1.0"?> <xsl:stylesheet version="1.0” xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:template match="people"> <html> <head><title>Знаменитые ученые</title></head> <body> <ul><xsl:apply-templates select="person" mode="toc"/></ul> <xsl:apply-templates select="person"/> </body> </html> </xsl:template> <!-- Шаблоны режима оглавления --> <xsl:template match="person" mode="toc“> <xsl:apply-templates select="name" mode="toc"/> </xsl:template> <xsl:template match="name" mode="toc"> <li><xsl:value-of select="last_name"/>, <xsl:value-of select="first_name"/></li> </xsl:template> <!-- Шаблоны обычного режима --> <xsl:template match="person“> <p><xsl:apply-templates/></p> </xsl:template> </xsl:stylesheet>


Слайд 71

Результат <html> <head> <title>Знаменитые ученые</title> </head> <body> <ul> <li>Тьюринг, Алан</li> <li>Фейнман, Ричард</li> </ul> <p> Алан Тьюринг специалист по информатике математик криптограф </p> <p> Ричард М Фейнман физик Игра на бонгах </p> </body> </html>


Слайд 72

Результат <?xml version="1.0" encoding="utf-8"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="xml" indent="yes"/> <xsl:template match="people"> <html> <head> <title>Знаменитые ученые</title> </head> <body> <dl> <xsl:apply-templates /> </dl> </body> </html> </xsl:template> <xsl:template match="person"> <dt> <xsl:apply-templates select="name"/> </dt> <dd> <ul> <li> Родился: <xsl:apply-templates select="@born"/> </li> <li> Умер: <xsl:apply-templates select="@died"/> </li> </ul> </dd> </xsl:template> </xsl:stylesheet>


Слайд 73

<?xml version="1.0" encoding="utf-8"?> <html> <head> <title>Знаменитые ученые</title> </head> <body> <dl> <dt> Алан Тьюринг </dt><dd><ul><li> Родился: 1912</li><li> Умер: 1954</li></ul></dd> <dt> Ричард Ф Фейнман </dt><dd><ul><li> Родился: 1918</li><li> Умер: 1988</li></ul></dd> </dl> </body> </html>


Слайд 74

Фильтрация XML данных Значение, которое присваивается атрибутам «match» или «select», представляет собой образец, соответствующий одному или нескольким элементам в XML-документе. атрибут «match» используется для элемента template, атрибут «select» – для элементов «value-of», «for-each» и «apply-templates». Количество элементов, соответствующих шаблону, можно ограничить с помощью фильтров. Фильтр это выражение, заключенное в квадратные скобки ([]) и следующее непосредственно за оператором пути. Например, образец, присвоенный следующему атрибуту match, указывает, что соответствующий элемент должен носить имя BOOK, и кроме того (это определяется фильтром), должен иметь дочерний элемент BINDING, который содержит текст "trade paperback": <xsl:template match="BOOK[BINDING='trade paperback']">


Слайд 75

Если в фильтр включено только имя элемента, то соответствующий элемент должен иметь дочерний элемент с указанным именем. Например, следующий образец отвечает любому элементу ITEM, имеющему дочерний элемент с именем CD, независимо от содержимого элемента CD: match="ITEM[CD]" Следующий образец отвечает любому элементу SHIRT, имеющему дочерний элемент COLOR, содержащий текст "red": match="SHIRT[COLOR='red']" А следующий образец, наоборот, отвечает любому элементу SHIRT, имеющему дочерний элемент COLOR, который не содержит текст "red": select="SHIRT[COLOR!='red']" Примечание. Если элемент имеет более одного дочернего элемента с именем, указанным в условии фильтрации, оператор сравнения применяется только к первому дочернему элементу. Например, если элемент SHIRT имеет два дочерних элемента COLOR, образец "SHIRT[COLOR='red']" будет отвечать элементу, только если первый элемент COLOR содержит слово "red".


Слайд 76

Если опустить атрибут «select» для XSLT-элемента «value-of», элемент будет осуществлять вывод текстового содержимого плюс текстовое содержимое всех дочерних элементов текущего элемента.


Слайд 77

Сортировка данных XML C помощью атрибута «order-by» в элементах «for-each» и «apply-templates», можно задавать порядком, в котором XSLT-процессор будет обрабатывать элементы, тем самым осуществляя сортировку данных XML. Можете назначать атрибуту «order-by» один или несколько образцов, разделяя их точкой с запятой. XSLT-процессор будет сортировать элементы с использованием образцов в том порядке, в котором они перечислены. Для указания направления сортировки (по возрастанию или по убыванию) следует предварить образец префиксом + или – . Например, атрибут order-by, установленный для следующего элемента for-each, предписывает браузеру сортировать элементы BOOK по фамилиям авторов в порядке возрастания, а также осуществлять сортировку для одинаковых фамилий по именам, также по возрастанию: <xsl:for-each select="INVENTORY/BOOK" order-by="+AUTHOR/LASTNAME; +AUTHOR/FIRSTNAME">


Слайд 78

В другом примере следующая установка «order-by» осуществляет сортировку элементов BOOK по названиям книг по убыванию: <xsl:apply-templates select="INVENTORY/BOOK" order-by="-TITLE"> Присваиваемый атрибуту «order-by» оператор пути, действует относительно образца, назначенного атрибуту select. Например установка order-by="-TITLE" указывает на элемент TITLE внутри элемента BOOK, вложенного в элемент INVENTORY.


Слайд 79

Работа с XML атрибутами XSLT рассматривает атрибут, принадлежащий элементу в XML-документе, как дочерний элемент. В XPath маршрутах в ссылках на атрибуты перед их именем должен ставиться символом @, указывающий на то, что имя относится к атрибуту, а не к элементу. Например, фильтр в следующем начальном тэге выделяет все элементы BOOK с атрибутом InStock, имеющем значение "yes". Другими словами, он выбирает только книги, которые имеются в наличии: <xsl:for-each select="INVENTORY/BOOK[@InStock='yes']"> Можете использовать XSLT-элемент value-of для извлечения значений атрибута точно так же, как вы это делаете для извлечения текстового содержимого элемента. Например, следующий элемент value-of получает значение атрибута Born, принадлежащего элементу AUTHOR: <xsl:value-of select="AUTHOR/@Born"/>


Слайд 80

Пример работы с атрибутами <?xml version="1.0" encoding="utf-8"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform” > <xsl:output method="xml" indent="yes"/> <xsl:template match="/"> <html> <xsl:apply-templates select="people"/> </html> </xsl:template> <xsl:template match="people"> <table> <xsl:apply-templates select="person"/> </table> </xsl:template> <xsl:template match="person"> <tr> <td> <xsl:value-of select="name"/></td> <td> <xsl:value-of select="@born"/> </td> <td> <xsl:value-of select="@died"/> </td> </tr> </xsl:template> </xsl:stylesheet>


Слайд 81

Результат <?xml version="1.0" encoding="utf-8"?> <html> <table> <tr> <td> Алан Тьюринг </td> <td>1912</td> <td>1954</td> </tr> <tr> <td> Ричард Ф Фейнман </td> <td>1918</td> <td>1988</td> </tr> </table> </html>


Слайд 82

Таблица стилей XSLT, использующая полный синтаксис XPath <?xml version="1.0" encoding="utf-8"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl"> <xsl:output method="xml" indent="yes"/> <xsl:template match="/"> <dl> <xsl:apply-templates select="descendant::person"/> </dl> </xsl:template> <xsl:template match="person"> <dt> <xsl:value-of select="child::name"/> </dt> <dd> <ul> <xsl:apply-templates select="child::name/following-sibling::*"/> </ul> </dd> </xsl:template> <xsl:template match="*"> <li> <xsl:value-of select="self::*"/> </li> </xsl:template> <xsl:template match="homepage" xmlns:XLink="http://www.w3.org/1999/XLink"> <li> <xsl:value-of select="attribute::XLink:href"/> </li> </xsl:template> </xsl:stylesheet>


Слайд 83

<?xml version="1.0" encoding="utf-8"?> <dl> <dt> Алан Тьюринг </dt> <dd> <ul> <li>специалист по информатике</li> <li>математик</li> <li>криптограф</li> </ul> </dd> <dt> Ричард Ф Фейнман </dt> <dd> <ul> <li>физик</li> <li>Игра на бонгах</li> </ul> </dd> </dl>


Слайд 84

Декларация xsl:variable Элемент xsl:variable определяет имя объекта (константу), которому можно задать начальное значение, но нельзя менять. Такое имя удобно использовать в тех случаях, когда объект надо использовать во многих местах таблицы стилей, а его вычисление сложно или громоздко. Элемент xsl:variable имеет следующие атрибуты: обязательный атрибутом «name» задает уточненное имя XML типа QName. в атрибуте «select» переменной можно задать сам объект, в атрибуте «as» определить тип объекта. Например, переменная var1 будет хранить число элементов “person”: <xsl:variable name="var1" select="count(//person)" as="xs:integer" /> Объект может быть получен из содержимого элемента xsl: variable: <xsl: variable name="var2">10</xsl:variable> или создан конструктором последовательности: <xsl:variable name="var3"> <xsl:value-of select="count (//person) " /> <xsl:variable>


Слайд 85

Для получения значения переменной определенной элементом xsl:variable, надо перед именем переменной поставить знак доллара: $varl, $var2. При использовании переменной следует учитывать ее область действия. Областью действия переменной является весь элемент, в котором она определена, начиная с места определения и включая вложенные элементы, если только в них не определено то же самое имя. Имена, определенные непосредственно в корневом элементе xsl:stylesheet, называются глобальными именами, остальные — локальными именами.


Слайд 86

Декларация xsl:param Элемент xsl:param задает параметр преобразования, Элемент xsl:param может записываться непосредственно в элементе xsl:stylesheet для задания параметра преобразования, в элементе xsl:template для задания параметра правила, элементе xsl:function для задания аргумента функции. Элемент xsl:param использует следующие атрибуты: обязательный атрибут «name», определяющий имя параметра. необязательный атрибут «select», в котором записывается выражение для получения значения параметра: необязательный атрибут «as» содержит желательный тип, к которому будет приведено значение параметра. атрибут «required», принимающий значения yes или nо (по умолчанию), указывает обязательность параметра: Если параметр обязателен, required="yes", то элемент xsl:param должен быть пустым и не содержать атрибут select. В этом случае он получит определенное значение при вызове функции или элементом xsl:with-param при вызове шаблона.


Слайд 87

Пример описания параметра: <xsl:param name="pl" select="10 + 20" /> Параметр получает значение Из атрибута “select”; Если нет атрибута “select”, то значение параметра берется из содержимого элемента, которым может быть конструктор последовательности узлов и атомарных значений: <xsl:param name="p2">10</xsl:param> Если отсутствует и атрибут select, и содержимое элемента, то параметр получает значение пустой строки. Для получения значения параметра перед его именем надо записывать знаком ‘$’: &p1, &p2. Например: <xsl:when test= "&p1=10 "> Правила, определяющие область видимости параметров, такие же, как и у имен объектов, определенных декларацией xsl:variable.


Слайд 88

Элемент xsl:with-param Элемент xsl:with-param ссылается на некоторый параметр, имя которого задается в обязательном атрибуте «name». обязательный атрибуте «name» необязательный атрибут «select» с его помощью можно задать выражение, результат вычисления которого будет новым значением параметра: <xsl:with-param name="pl" select="100 * 20" /> Новое значение можно задать и в содержимом элемента: <xsl:with-param name="pl">100</xsl:with-param> Элемент xsl:with-param используется только в инструкциях xsl:apply-templates, xsl:apply-imports, xsl:call-template.


Слайд 89

Декларация xsl:function Элемент xsl:function позволяет описывать обычные пользовательские функции. в обязательном атрибуте «nаmе» задается имя функции. Имя функции - это уточненное имя типа QName, причем оно должно обязательно записываться с префиксом. в необязательным атрибутом «аs» можно указать тип функции. В элементе описания функции записываются элементы с аргументами и тело функции. с помощью элементов xsl:param задаются аргументы функции. в содержимом элемента xsl:function задается тело функции. Это конструктор последовательности. Результатом функции будет последовательность, созданная конструктором. Все аргументы функции позиционные, следовательно, все элементы xsl:param должны быть записаны в начале тела функции и порядок их записи имеет значение при вызове функции. У аргументов функции не может быть значений по умолчанию, следовательно, элементы xsl:param должны быть пустыми и у них не должно быть атрибутов select.


Слайд 90

Пример функции Например: <xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:usr="http://myexamples.com" xmlns:xs="http://www.w3.org/2001/XMLSchema"> <xsl: function nаme= “usr:sum" as="xsl:integer"> <xsl:param name="x" as="xsl:integer" /> <хsl:раrаm name="y" as="xsl:integer" /> <xsl:value-of select="$x + $y" /> </xsl:function> вызвать функцию можно в любом выражении подходящего типа, записав ее имя и аргументы в скобках. Например: <хsl:value-of select="10 + 2 * usr:sum(2, 3)" />


Слайд 91

Инструкции управления


Слайд 92

Инструкции управления xsl:if Элемент «xsl:if» запускает конструктор последовательности, содержащийся в его теле, только если выражение, записанное в обязательном и единственном атрибуте «test», является истинным : <xsl:if test="$x > $у"> <xsl:value-of select="$x" /> больше <xsl:value-of select="$y" /> </xsl:if>


Слайд 93

Инструкции управления xsl:for-each Элемент «xsl:for-each» задает цикл, выполняющийся для каждого элемента последовательности, полученной в результате вычисления выражения атрибута «select». У элемента «xsl:for-each» имеет один обязательны атрибуте «select», в котором задается выражение, дающее в результате последовательность. Для каждого члена этой последовательности выполняется конструктор, содержащийся в теле элемента xsl:for-each.


Слайд 94

Инструкция управления xsl:choose У элемента xsl:choose нет ни одного атрибута, но в его теле записывается один или несколько элементов «xsl:when» (варианты) и один необязательный элемент «xsl:otherwise»: Например: <xsl:choose> <xsl when test="$day=l">Понедельник</xsl:when> <xsl when test="$day=2">Bторник</xsl:when> <xsl when test="$day=3">Cреда</xsl:when> <xsl when test="$day=4">Четверг</xsl:when> <xsl when test="$day=5">Пятница</xsl:when> <xsl when test="$day=6">Cy66oтa</xsl:when> <xsl when test="$day=7">Bocкpeceнье</xsl:when> <xsl otherwise>Ошибка определения дня нeдeли</xsl:otherwise> </xsl:choose>


Слайд 95

Элемент xsl:when имеет один обязательный параметр «test», содержащий логическое выражение, тело, содержащее конструктор последовательности. Элемент xsl: otherwise не имеет атрибутов, есть только тело, содержащее конструктор последовательности. В инструкции xsl: choose всегда выполняется не больше одного варианта. Элементы xsl:when (варианты) просматриваются в порядке их записи в инструкции xsl:choose. Как только будет найден вариант с истинным значением выражения test, он будет выполнен, и результат этого варианта будет результатом всей инструкции. Варианты, следующие за ним по порядку, не рассматриваются. Если ни один вариант не подойдет, то результатом инструкции будет результат конструктора, записанного в элементе xsl:otherwise. Если элемента xsl:otherwise в инструкции нет, то результатом будет пустая строка.


Слайд 96

Инструкция xsl:for-each-group Группы узлов создаются одним из четырех атрибутов элемента xsl:for-each-group: group-by, group-adjacent, group-starting-with, group-ending-with. В каждом элементе xsl:for-each-group должен быть один и только один из этих атрибутов. Полученные группы существуют и могут использоваться только в содержимом элемента xsl:for-each-group. В теле элемента xsl:for-each-group записывается конструктор последовательности, который выполняется по одному разу для каждой группы.


Слайд 97

Первый способ группировки Элемент xsl:for-each-group отбирает последовательность узлов и атомарных значений своим обязательным атрибутом select и группирует ее элементы по признаку, заданному выражением, записанным в атрибуте «group-by». Этот признак называется ключом группы. Ключ группы вычисляется заново для каждого элемента последовательности. В результате исходная последовательность, отобранная атрибутом select, разбивается на несколько последовательностей. В следующем примере в одну группу собираются все узлы-элементы name с одинаковым значением атрибута surname: <xsl:for-each-group select="name" group-by="@surname"> Выражение, являющееся значением атрибута group-by, может давать несколько ключей группы, и один узел может попасть сразу в несколько групп. Например: <xsl:for-each-group select="name" group-by="(@second, @surname)">


Слайд 98

Второй способ группировки Второй способ разбить последовательность на группы дает атрибут «group-adjacent». Он собирает в группу все подряд идущие элементы последовательности с одинаковым значением ключа. Такой отбор возможен, если в атрибуте group-adjacent содержится только один ключ группы. Процессор XSLT следит за тем, чтобы значением атрибута group-adjacent был один и только один ключ группы.


Слайд 99

Третий и четвертый способы группировки Третий и четвертый способы применимы к последовательностям, состоящим только из узлов, без атомарных значений. Эти способы применяют атрибут «group-starting-with» или «атрибут group-ending-with». Значением этих атрибутов может быть не любое выражение, а только образец. В одну группу собираются все подряд идущие узлы, первый (последний) из которых удовлетворяет образцу. Остальные узлы из этой группы не будут удовлетворять образцу. Если несколько подряд идущих элементов последовательности удовлетворяют образцу, то они попадут в разные группы.


Слайд 100

Функции работы с группами Для удобства работы с группами в язык XSLT введены две функции без аргументов current-group() - результатом является последовательность— текущая группа; current-group-key () - результатом является значение ключа текущей группы. Их можно использовать только в теле элемента xsl:for-each-group.


Слайд 101

Пояснение работы XSLT трансформации с помощью использования именованных шаблонов


Слайд 102

XSLT работает следующим образом Загружает входной документ в виде DOM дерева (внутренне процессор оптимизирует работу с DOM, но для пояснения работы процессора это не важно). Выполняет обход дерева входного документа по принципу «вначале в глубину» (depth-first walk) (это обычный алгоритм обхода деревьев из теории алгоритмов) (но это если используется инструкция <xsl:apply-templates/> ???? Или в результате использования шаблона по умолчанию ????). По мере обхода документа выполняется выбор шаблона (template) в таблице преобразования (stylesheet) для текущего узла (node). Выполняется применение данного шаблона, который описывает, как создать ноль, один или несколько узлов (nodes) в формируемом дереве (output tree). В результате выполнения обхода из входного дерева и правил, заданных в шаблонах, создается новое дерево (выходное дерево). Выходное дерево записывается в соответствии с HTML или XML синтаксисом.


Слайд 103

Пример XML-документа с описанием статьи <?xml version="1.0"?> <db:article xmlns:db="http://ananas.org/2002/docbook/subset"> <db:title>XSLT, JSP and PHP</db:title> <db:section> <db:title>Is there a difference?</db:title> <db:para>Yes there is! XSLT is a pure XML technology that traces its roots to <db:emphasis>tree manipulation algorithms</db:emphasis>. JSP and PHP offer an ingenious solution to combine scripting languages with HTML/XML tagging.</db:para> <db:para>The difference may not be obvious when you're first learning XSLT (after all, it offers tags and instructions), but understanding the difference will make you a <db:emphasis role="bold">stronger and better</db:emphasis> developer.</db:para> </db:section> <db:section> <db:title>How do I learn the difference?</db:title> <db:para>Interestingly enough, you can code the XSLT algorithm in XSLT... one cool way to experiment with the difference.</db:para> </db:section> </db:article>


Слайд 104

Как процессор видит XML документ


Слайд 105

Пример 1: простое преобразования XML документа в HTML <?xml version="1.0"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:db="http://ananas.org/2002/docbook/subset"> <xsl:output method="html"/> <xsl:template match="db:article"> // поиск корневого элемента ??? <html> <head> <title> <xsl:value-of select="db:articleinfo/db:title"/> </title></head> <body> <xsl:apply-templates/> // выполняется обход «сначала вглубь» ??? </body> </html> </xsl:template> <xsl:template match="db:para"> <p><xsl:apply-templates/></p> // выполняется обход «сначала вглубь» ??? </xsl:template> <xsl:template match="db:ulink"> <a href="{@url}"><xsl:apply-templates/></a> // выполняется обход «сначала вглубь» ??? </xsl:template> <xsl:template match="db:article/db:title"> <h1><xsl:apply-templates/></h1> // выполняется обход «сначала вглубь» ??? </xsl:template> <xsl:template match="db:title"> <h2><xsl:apply-templates/></h2> // выполняется обход «сначала вглубь» ??? </xsl:template> <xsl:template match="db:emphasis[@role='bold']"> <b><xsl:apply-templates/></b> </xsl:template> <xsl:template match="db:emphasis“> <i><xsl:apply-templates/></i> // выполняется обход «сначала вглубь» ??? </xsl:template> </xsl:stylesheet>


Слайд 106

Пример 2  Пример 2 является аналогом примера 1, но в нем обход дерева выполняется более явно. Вместо того, чтобы рассчитывать, что процессор будет выполнять обход, данное преобразование использует именованный шаблоны «main», который реализует требуемый обход дерева.  Именованный шаблоны«main» является рекурсивной функцией, которая принимает набор узлов в текущем аргументе и выполняет циклы по этому множеству узлов. Основной частью данного шаблона является инструкция «choose», которая пытается найти наиболее подходящие правила для рассматриваемого узла (given node). При обработке узла (node), данный шаблон рекурсивно вызывает себя для обработки дочерних узлов текущего узла.


Слайд 107

Именованные шаблоны Именованный шаблон это шаблон, котором задан атрибут «name». Он принимает переданные параметры с помощью инструкции «xsl:param». Например: <xsl:template name="print"> <xsl:param name="message"/> <!-- template content goes here --> </xsl:template> Вызов на выполнение именованного шаблона выполняется с помощью инструкции xsl:call-template (вместо использования инструкции xsl:apply-templates). Например: <xsl:call-template name="print"> <xsl:with-param name="message" select="'See if it prints this message.'"/> </xsl:call-template>


Слайд 108

Пример 2 таблицы преобразования, явно задающую порядок обхода вершин <?xml version="1.0"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:db="http://ananas.org/2002/docbook/subset"> <xsl:output method="html"/> <xsl:template match="/"> <xsl:call-template name="main"> <xsl:with-param name="nodes" select="."/> // задается параметр </xsl:call-template> </xsl:template> <xsl:template name="main"> <xsl:param name="nodes"/> <xsl:for-each select="$nodes"> // цикл по параметрам <xsl:choose> // задается параметр <xsl:when test="self::db:article"> // если это элемент db:article <html> <head><title> <xsl:value-of select="db:title"/> </title></head> <body> <xsl:call-template name="main"> // рекурсивный вызов !? <xsl:with-param name="nodes" select="child::node()"/> </xsl:call-template> </body> </html> </xsl:when>


Слайд 109

<xsl:when test="self::db:para"> <p> <xsl:call-template name="main"> <xsl:with-param name="nodes" select="child::node()"/> </xsl:call-template> </p> </xsl:when> <xsl:when test="self::db:ulink"> // если это элемент db:ulink <a href="{@url}"> <xsl:call-template name="main"> // рекурсивный вызов !? <xsl:with-param name="nodes" select="child::node()"/> </xsl:call-template> </a> </xsl:when> <xsl:when test="self::db:title[parent::db:article]"> // если это элемент db:title[parent::db:article <h1> <xsl:call-template name="main"> // рекурсивный вызов !? <xsl:with-param name="nodes" select="child::node()"/> </xsl:call-template> </h1> </xsl:when> <xsl:when test="self::db:title"> // если это элемент db:title <h2> <xsl:call-template name="main"> // рекурсивный вызов !? <xsl:with-param name="nodes" select="child::node()"/> </xsl:call-template> </h2> </xsl:when>


Слайд 110

<xsl:when test="self::db:emphasis[@role='bold']"> <b> <xsl:call-template name="main"> // рекурсивный вызов !? <xsl:with-param name="nodes" select="child::node()"/> </xsl:call-template> </b> </xsl:when> <xsl:when test="self::db:emphasis“> <i> <xsl:call-template name="main"> // рекурсивный вызов !? <xsl:with-param name="nodes" select="child::node()"/> </xsl:call-template> </i> </xsl:when> <xsl:when test="self::text()"> <xsl:value-of select="."/> </xsl:when> <xsl:otherwise> <xsl:call-template name="main"> // рекурсивный вызов !? <xsl:with-param name="nodes" select="child::node()"/> </xsl:call-template> </xsl:otherwise> </xsl:choose> </xsl:for-each> </xsl:template> </xsl:stylesheet>


Слайд 111

Рекомендация На практике не используется явный способ обхода вершин графа (как показано в примере 2). XSLT процессор обеспечивает базовое выполнение обхода «depth-first» (такое, как выполнение цикла и передача параметров). Например, для обработки элементов db:emphasis начинающие разработчики могут записать следующий код: <xsl:template match="db:emphasis"> // если встречается элемент выделения текста «db:emphasis» <xsl:choose> <xsl:when test="@role='bold'"> // если задан атрибут role='bold‘, // то «жирный шрифт» <b><xsl:apply-templates/></b> </xsl:when> <xsl:otherwise> <i><xsl:apply-templates/></i> // иначе «курсив» </xsl:otherwise> </xsl:choose> </xsl:template>


Слайд 112

Однако зная порядок работы XSLT процессора проще записать следующий полностью эквивалентный код: <xsl:template match="db:emphasis[@role='bold']"> <b><xsl:apply-templates/></b> </xsl:template> <xsl:template match="db:emphasis"> <i><xsl:apply-templates/></i> </xsl:template>


Слайд 113

Функция id() Образец может начинаться с вызова функции id() или функции key(). Единственным аргументом функции id() служит уникальный идентификатор узла, т.е. значение его атрибута типа id. Например, образцу id(@xref) соответствует узел-элемент, на идентификатор которого ссылается значение атрибута xref. Образцу id("h12") соответствует узел-элемент с идентификатором h12, а образцу id("h12")//street — его потомки street любого уровня вложенности. Функция id(), работающая с атрибутами типа id, подвержена всем ограничениям этого типа, а именно: у элемента может быть только один атрибут типа id, значит, можно cсылаться только на этот атрибут, не говоря уже о том, что такой атрибут может вообще отсутствовать: значение атрибута типа id уникально, значит, нельзя обратиться сразу к нескольким элементам; значение атрибута типа id может быть только именем типа Name, значит, не может быть числом, содержать пробелы и многие другие символы; схема, в которой определен тип id атрибута, может оказаться недоступной для процессора XSLT и он не "узнает" тип атрибута; функция id() работает только с атрибутами, но не с элементами, их содержимым и прочими узлами дерева документа; для внесения новых перекрестных ссылок в документ XML надо его менять, вставляя атрибуты типа id, что может быть нежелательно или невозможно.


Слайд 114

Функция key() Функция key() менее требовательна. Она снимает ограничения функции id(), обращаясь не к атрибуту элемента, находящегося в документе ХМL, а к атрибуту use специального элемента xsl:key, расположенного в таблице стилей. У нее два аргумента: имя ключа, задаваемое строкой типа QName; это значение атрибута name элемента xsl:key, позволяющее выбрать нужный элемент xsl:key. значение ключа, представляющее собой выражение, в результате вычисления которого получается последовательность из одного или нескольких атомарных значений типа xdt:anyAtomicType. Образец с функцией key() выглядит примерно так: key("addr", 230007)//street. Элемент xsl:key определяет ключ и множество значений, а функция key() выбирает из этого множества те значения, что совпадают со вторым аргументом функции key(). Таким образом, при необходимости создания новых ссылок в исходном документе XML, его не надо изменить, достаточно добавить новые элементы xml:key в таблицу стилей.


Слайд 115

Шаблоны значений атрибутов Легко включить известные значения атрибутов в выходной документ в виде строкового содержимого элемента результата. Например, данное шаблонное правило заключает каждый входной элемент person в HTMLэлемент span с атрибутом class, имеющим значение person: <xsl:template match="person"> <span class="person"><xsl:apply-templates/></span> </xsl:template>   Однако задача усложняется, если значение атрибута при написании таблицы стилей не известно и должно быть прочитано из входного документа. Решением будет использование шаблона значения атрибута. Шаблон значения атрибута – это выражение XPath, заключенное в фигурные скобки и помещаемое внутрь значения атрибута в таблице стилей. Когда процессор выводит этот атрибут, он заменяет шаблон значения атрибута на фактическое значение.


Слайд 116

Например, предположим, что составляется шаблон имени, который заменяет входные элементы name на пустые элементы с атрибутами first_name, middle_initial и last_name следующего вида: <name first="Ричард" initial="Ф" last="Фейнман"/> Такую задачу выполняет следующий шаблон: <xsl:template match="name"> <name first="{first_name}" initial="{middle_initial}" last="{last_name}" /> </xsl:template> Значение атрибута first в таблице стилей заменяется значением элемента first_name из входного документа, значение атрибута initial меняется на значение элемента middle_initial из входного документа, а значение атрибута last – на значение элемента last_name.


Слайд 117

Пример XML документа <?xml version="1.0"?> <people xmlns="http://namespaces.oreilly.com/people"> <person born="1912" died="1954“> <name> <first_name>Алан</first_name> <last_name>Тьюринг</last_name> </name> <profession>специалист по информатике</profession> <profession>математик</profession> <profession>криптограф</profession> </person> <person born="1918" died="1988"> <name> <first_name>Ричард</first_name> <middle_initial>Ф</middle_initial> <last_name>Фейнман</last_name> </name> <profession>физик</profession> <hobby>Игра на бонгах</hobby> </person> </people>


Слайд 118

Пример XSLT преобразования <?xml version="1.0"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:pe="http://namespaces.oreilly.com/people"> <xsl:template match="pe:people"> <html> <head><title>Знаменитые ученые</title></head><body> <xsl:apply-templates/> </body></html> </xsl:template> <xsl:template match="pe:name"> <p><xsl:value-of select="pe:last_name"/>, <xsl:value-of select="pe:first_name"/></p> </xsl:template> <xsl:template match="pe:person"> <xsl:apply-templates select="pe:name"/> </xsl:template> </xsl:stylesheet>


Слайд 119

Элемент <stylesheet> содержит три шаблона, каждый из которых вложен в элемент <template>. В таблице стилей этот элемент фактически называется <xsl:template>, так как задано пространство имен. У элемента <template> есть атрибут match, значением которого является образец (pattern) в форме выражения XPath. С ним сравнивается узел дерева, к которому применяется шаблон. Прежде всего процессору XSL надо сообщить желаемую форму вывода. Узнав ожидаемый формат вывода, процессор начнет исследовать исходный документ с корневого узла.


Слайд 120

XML документ <?xml version="1.0" encoding="utf-8"?> <?xml-stylesheet type="text/xsl" href="XslDemo06.xsl"?> <INVENTORY> <BOOK InStock="yes“> <TITLE>The Adventures of Huckleberry Finn</TITLE> <AUTHOR Born="1835">Mark Twain</AUTHOR> <BINDING>mass market paperback</BINDING> <PAGES>298</PAGES> <PRICE>$5.49</PRICE> </BOOK> <BOOK InStock="no"> <TITLE>Leaves of Grass</TITLE> <AUTHOR Born="1819">Walt Whitman</AUTHOR> <BINDING>hardcover</BINDING> <PAGES>462</PAGES> <PRICE>$7.75</PRICE> </BOOK> <BOOK InStock="yes"> <TITLE>The Marble Faun</TITLE> <AUTHOR Born="1804">Nathaniel Hawthorne</AUTHOR> <BINDING>trade paperback</BINDING> <PAGES>473</PAGES> <PRICE>$10.95</PRICE> </BOOK> <BOOK InStock="yes"> <TITLE>Moby-Dick</TITLE> <AUTHOR Born="1819">Herman Melville</AUTHOR> <BINDING>hardcover</BINDING> <PAGES>724</PAGES> <PRICE>$9.95</PRICE> </BOOK> </INVENTORY>


Слайд 121

<?xml version="1.0" encoding="utf-8"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform”> <xsl:output method="html" indent="yes"/> <xsl:template match="/"> <HTML> <TITLE> Список книг </TITLE> <BODY> <H2>Книги на складе</H2> <TABLE BORDER="1" CELLPADDING="5"> <THEAD> <TH>Название</TH> <TH>Автор</TH> <TH>Тип переплета</TH> <TH>Кол-во страниц</TH> <TH>Цена</TH> </THEAD> <xsl:for-each select="INVENTORY/BOOK[@InStock='yes']"> <TR ALIGN="CENTER"> <TD> <xsl:value-of select="TITLE"/> </TD> <TD> <xsl:value-of select="AUTHOR"/> <BR/> (born <xsl:value-of select="AUTHOR/@Born"/>) </TD> <TD> <xsl:value-of select="BINDING"/> </TD> <TD> <xsl:value-of select="PAGES"/> </TD> <TD> <xsl:value-of select="PRICE"/> </TD> </TR> </xsl:for-each> </TABLE> </BODY> </HTML> </xsl:template> </xsl:stylesheet>


Слайд 122


Слайд 123

Примеры XSLT преобразований XML документа в HTML документ


Слайд 124

Пример XML документа <?xml version="1.0" encoding="utf-8"?> <PlayList> <Track Id="1170056tuNb" Length="280"> <Artist>Рихард Вагнер</Artist> <Title>Полёт валькирии</Title> </Track> <Track Id="938304vu1E" Length="163"> <Artist>Эдвард Григ</Artist> <Title>В пещере горного короля</Title> </Track> <Track Id="35532014SEz" Length="187"> <Artist>Иоган Бах</Artist> <Title>Токката и фуга ре-минор</Title> </Track> <Track Id="264667GXiD" Length="203"> <Artist>Антонио Вивальди</Artist> <Title>Времена года. Лето. Шторм</Title> </Track> <Track Id="613982Fj9E" Length="103"> <Artist>Джузеппе Верди</Artist> <Title>Триумфальный марш (Аида)</Title> </Track> </PlayList>


Слайд 125

Требуется создать список


Слайд 126

Пример XSLT преобразования <?xml version="1.0" encoding="utf-8"?> <!DOCTYPE xsl:stylesheet [ <!ENTITY mdash "&#8212;"> ]> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="xml" indent="yes" omit-xml-declaration="yes"/>   <xsl:template match="/"> <xsl:apply-templates select="PlayList"/> // тоже самое без select="PlayList" </xsl:template>   <xsl:template match="PlayList"> <ul> <xsl:apply-templates select="Track"/> </ul> </xsl:template>   <xsl:template match="Track"> <li> <a href="http://prostopleer.com/tracks/{@Id}"> <xsl:value-of select="Artist"/> <xsl:text> &mdash; </xsl:text> <xsl:value-of select="Title"/> </a> </li> </xsl:template> </xsl:stylesheet>


Слайд 127

Данное XSLT-преобразование состоит из трёх шаблонов (xsl:template). Каждый шаблон обслуживает свою сущность, что даёт возможность легко вносить изменения и делает код понятным. Если требуется поменять отображение списка (например, добавить атрибут class), то надо редактировать шаблон match="PlayList". Если требуется изменить отображение элементов списка, то следует менять шаблон match="Track"  Фактически, XSLT не только даёт возможность разделить данные и представление, но и позволяет разделить представления различных сущностей. Конечно, в более сложных случаях добиться такого разделения бывает сложно.


Слайд 128

Получаемый результат <ul> <li> <a href="http://prostopleer.com/tracks/1170056tuNb"> Рихард Вагнер — Полёт валькирии</a> </li> <li> <a href="http://prostopleer.com/tracks/938304vu1E"> Эдвард Григ — В пещере горного короля</a> </li> ... </ul>


Слайд 129

Получаемый результат преобразования <ul> <li> <a href="http://prostopleer.com/tracks/1170056tuNb">Рихард Вагнер — Полёт валькирии</a> </li> <li> <a href="http://prostopleer.com/tracks/938304vu1E">Эдвард Григ — В пещере горного короля</a> </li> <li> <a href="http://prostopleer.com/tracks/35532014SEz">Иоган Бах — Токката и фуга ре-минор</a> </li> <li> <a href="http://prostopleer.com/tracks/264667GXiD">Антонио Вивальди — Времена года. Лето. Шторм</a> </li> <li> <a href="http://prostopleer.com/tracks/613982Fj9E">Джузеппе Верди — Триумфальный марш (Аида)</a> </li> </ul>


Слайд 130

Немного измененное преобразование <?xml version="1.0" encoding="utf-8"?> <!DOCTYPE xsl:stylesheet [ <!ENTITY mdash "&#8212;"> ]> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="xml" indent="yes" omit-xml-declaration="yes"/> <xsl:template match="/"> <ul> <xsl:apply-templates /> </ul> </xsl:template> <xsl:template match="Track"> <li> <a href="http://prostopleer.com/tracks/{@Id}"> <xsl:value-of select="Artist"/> <xsl:text> &mdash; </xsl:text> <xsl:value-of select="Title"/> </a> </li> </xsl:template> </xsl:stylesheet>


Слайд 131

Результат такой же <ul> <li><a href="http://prostopleer.com/tracks/1170056tuNb">Рихард Вагнер — Полёт валькирии</a></li> <li><a href="http://prostopleer.com/tracks/938304vu1E">Эдвард Григ — В пещере горного короля</a></li> <li><a href="http://prostopleer.com/tracks/35532014SEz">Иоган Бах — Токката и фуга ре-минор</a></li> <li><a href="http://prostopleer.com/tracks/264667GXiD">Антонио Вивальди — Времена года. Лето. Шторм</a></li> <li><a href="http://prostopleer.com/tracks/613982Fj9E">Джузеппе Верди — Триумфальный марш (Аида)</a></li> </ul>


Слайд 132

Отметим, что в приведенном примере используется сущность “&mdash;”, которая определяется в начале XSLT-документа  <!DOCTYPE xsl:stylesheet [ <!ENTITY mdash "&#8212;"> ]> Таким образом, &mdash; выводится, как символ с кодом &#8212;.  Если нужно вывести строку «какая она есть», то стоит использовать CDATA следующим образом: <xsl:text disable-output-escaping="yes"> <![CDATA[ &mdash; ]]> </xsl:text>


Слайд 133

Элемент xsl:text Элемент xsl:text позволяет контролировать, что именно будет содержать TEXT-элемент. Если элемент xsl:text не использовать: <xsl:template match="Track"> <li> <a href="http://prostopleer.com/tracks/{@Id}"> <xsl:value-of select="Artist"/> &mdash; <xsl:value-of select="Title"/> </a> </li> </xsl:template> То в результате получается следующий HTML код: <li> <a href="http://prostopleer.com/tracks/264667GXiD"> Антонио Вивальди – Времена года. Лето. Шторм </a> </li> Т.е., отсутствие элемента xsl:text привело к появлению в HTML лишних переводов строк и пробелов.


Слайд 134

Конечно, можно написать XSLT преобразование и без xsl:text, следующим образом:  <xsl:template match="Track"> <li> <a href="http://prostopleer.com/tracks/{@Id}"> <xsl:value-of select="Artist"/> &mdash; <xsl:value-of select="Title"/> </a> </li> </xsl:template> Но такой шаблон тяжелее читать и есть больше возможности, при сопровождении, сделать в нем ошибку. Нужно стараться, чтобы форматирование XSLT-шаблона не влияло на результат трансформации. Именно хорошая практикой считается использование элемента xsl:text.


Слайд 135

Ветвление Для ветвления в XSLT есть специальные элементы: xsl:if и xsl:choose. Но ими не следует сильно злоупотреблять. Лучше использовать приёмы, позволяющие не загромождать преобразование ветвлениями.


Слайд 136

Решение с использованием xsl:choose <?xml version="1.0" encoding="utf-8"?> <!DOCTYPE xsl:stylesheet [ <!ENTITY mdash "&#8212;"> ]> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="xml" indent="yes" omit-xml-declaration="yes"/>   <xsl:template match="/"> <xsl:apply-templates select="PlayList"/> </xsl:template>   <xsl:template match="PlayList"> <xsl:choose> <xsl:when test="count(Track) = 0"> <div> <xsl:text><![CDATA[Список пуст]]></xsl:text> </div> </xsl:when> <xsl:otherwise> <ul> <xsl:apply-templates select="Track"/> </ul> </xsl:otherwise> </xsl:choose> </xsl:template>   <xsl:template match="Track"> <li> <a href="http://prostopleer.com/tracks/{@Id}"> <xsl:value-of select="Artist"/> <xsl:text> &mdash; </xsl:text> <xsl:value-of select="Title"/> </a> </li> </xsl:template> </xsl:stylesheet> Пример использования ветвлений: дополнение предыдущего примера возможностью выводить сообщения «Список пуст» в случае, если PlayList не содержит элементов Track.


Слайд 137

Решение с использованием дополнительного шаблона <?xml version="1.0" encoding="utf-8"?> <!DOCTYPE xsl:stylesheet [ <!ENTITY mdash "&#8212;"> ]> <xsl:stylesheet version="1.0” xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="xml" indent="yes" omit-xml-declaration="yes"/> <xsl:template match="/"> <xsl:apply-templates select="PlayList"/> </xsl:template> <xsl:template match="PlayList[count(Track) = 0]" > <div> <xsl:text><![CDATA[Список пуст]]></xsl:text> </div> </xsl:template> <xsl:template match="PlayList"> <ul> <xsl:apply-templates select="Track"/> </ul> </xsl:template>   <xsl:template match="Track"> <li><a href="http://prostopleer.com/tracks/{@Id}"> <xsl:value-of select="Artist"/> <xsl:text> &mdash; </xsl:text> <xsl:value-of select="Title"/> </a> </li> </xsl:template> </xsl:stylesheet>


Слайд 138

Второе решение, является более эффектным: новая функциональность не добавила нового кода в старые шаблоны, новый шаблон максимально изолирован. Если понадобится добавить картинку к сообщению о пустом списке, то в первом случае скорее всего будет сделано дополнение к элементу xsl:when в шаблоне match="PlayList". А вот во втором случае изменения будут только в специализированном шаблоне. В предыдущем примере было выполнено разделение на две абсолютно разные ветки отображения элемента списка. Если ветви различаются незначительно то использование xsl:if и xsl:choose вполне оправдано. Имеется другой подход: использование параметра mode у элемента xsl:template.


Слайд 139

Задание разных стилей на чётные и нечётные элементы списка <?xml version="1.0" encoding="utf-8"?> <!DOCTYPE xsl:stylesheet [ <!ENTITY mdash "&#8212;"> ]> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="xml" indent="yes" omit-xml-declaration="yes"/> <xsl:template match="PlayList"> <ul> <xsl:apply-templates select="Track"/> </ul> </xsl:template> <xsl:template match="Track“> <li> <xsl:attribute name="class"> <xsl:apply-templates select="." mode="add-track-class"/> </xsl:attribute> <a href="http://prostopleer.com/tracks/{@Id}"> <xsl:value-of select="Artist"/> <xsl:text> &mdash; </xsl:text> <xsl:value-of select="Title"/> </a></li> </xsl:template>   <xsl:template mode="add-track-class" match="Track[position() mod 2 = 0]" > <xsl:text>even</xsl:text> </xsl:template>   <xsl:template mode="add-track-class" match="Track" > <xsl:text>odd</xsl:text> </xsl:template>   </xsl:stylesheet>


Слайд 140

Результат <ul> <li class="odd"> <a href="http://prostopleer.com/tracks/1170056tuNb">Рихард Вагнер — Полёт валькирии</a> </li> <li class="even"> <a href="http://prostopleer.com/tracks/938304vu1E">Эдвард Григ — В пещере горного короля</a> </li> <li class="odd"> <a href="http://prostopleer.com/tracks/35532014SEz">Иоган Бах — Токката и фуга ре-минор</a> </li> <li class="even"> <a href="http://prostopleer.com/tracks/264667GXiD">Антонио Вивальди — Времена года. Лето. Шторм</a> </li> <li class="odd"> <a href="http://prostopleer.com/tracks/613982Fj9E">Джузеппе Верди — Триумфальный марш (Аида)</a> </li> </ul>


Слайд 141

Циклы и сортировка в XSLT Для циклов в XSLT есть элемент xsl:for-each, но аналогичные действия можно выполнить с помощью обычного элемента xsl:apply-templates. Например: требуется вывести список произведений, отсортированный по длительности.   <ul> <li>Рихард Вагнер — Полёт валькирии — 280</li> <li>Антонио Вивальди — Времена года. Лето. Шторм — 203</li> <li>Иоган Бах — Токката и фуга ре-минор — 187</li> <li>Эдвард Григ — В пещере горного короля — 163</li> <li>Джузеппе Верди — Триумфальный марш (Аида) — 103</li> </ul>


Слайд 142

Сортировка с использованием элемента xsl:for-each <?xml version="1.0" encoding="utf-8"?> <!DOCTYPE xsl:stylesheet [ <!ENTITY mdash "&#8212;“>]> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="xml" indent="yes" omit-xml-declaration="yes"/>   <xsl:template match="PlayList"> <ul> <xsl:for-each select="Track"> <xsl:sort select="@Length" data-type="number" order="descending"/> <li> <xsl:value-of select="concat(Artist, ' &mdash; ', Title, ' &mdash; ', @Length)"/> </li> </xsl:for-each> </ul> </xsl:template> </xsl:stylesheet>


Слайд 143

Сортировка с использованием элемента xsl:apply-templates <?xml version="1.0" encoding="utf-8"?> <!DOCTYPE xsl:stylesheet [ <!ENTITY mdash "&#8212;“> ]> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="xml" indent="yes" omit-xml-declaration="yes"/>   <xsl:template match="PlayList"> <ul> <xsl:apply-templates select="Track"> <xsl:sort select="@Length" data-type="number" order="descending"/> </xsl:apply-templates> </ul> </xsl:template>   <xsl:template match="Track"> <li> <xsl:value-of select="concat(Artist, ' &mdash; ', Title, ' &mdash; ', @Length)"/> </li> </xsl:template> </xsl:stylesheet>


Слайд 144

Как видно из кода, первый вариант короче и проще, но он нарушил принцип разделения ответственности для шаблонов. В этом варианте шаблон match="PlayList" стал содержать логику отображения элемента Track. Казалось бы, ничего страшного, но представим задачу, когда в списке встречаются композиции с ID и без ID. Для композиции с ID нужно показать ссылку, а для остальных вывести только текст.


Слайд 145

Вариант с использованием xsl:for-each <?xml version="1.0" encoding="utf-8"?> <!DOCTYPE xsl:stylesheet [<!ENTITY mdash "&#8212;“>]> <xsl:stylesheet version="1.0“ xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="xml" indent="yes" omit-xml-declaration="yes"/>  <xsl:template match="PlayList"> <ul> <xsl:for-each select="Track"> <xsl:sort select="@Length" data-type="number" order="descending"/><li> <xsl:choose> <xsl:when test="not(@Id)“> <xsl:apply-templates select="." mode="TrackName" /> </xsl:when> <xsl:otherwise> <a href="http://prostopleer.com/tracks/{@Id}"> <xsl:apply-templates select="." mode="TrackName" /> </a> </xsl:otherwise> </xsl:choose></li> </xsl:for-each> </ul> </xsl:template> <xsl:template match="Track" mode="TrackName"> <xsl:value-of select="concat(Artist, ' &mdash; ', Title, ' &mdash; ', @Length)"/> </xsl:template> </xsl:stylesheet>


Слайд 146

Результат <?xml version="1.0" encoding="utf-8"?> <PlayList> <Track Id="1170056tuNb" Length="280"> <Artist>Рихард Вагнер</Artist> <Title>Полёт валькирии</Title> </Track> <Track Length="163"> <Artist>Эдвард Григ</Artist> <Title>В пещере горного короля</Title> </Track> <Track Id="35532014SEz" Length="187"> <Artist>Иоган Бах</Artist> <Title>Токката и фуга ре-минор</Title> </Track> <Track Id="264667GXiD" Length="203"> <Artist>Антонио Вивальди</Artist> <Title>Времена года. Лето. Шторм</Title> </Track> <Track Id="613982Fj9E" Length="103"> <Artist>Джузеппе Верди</Artist> <Title>Триумфальный марш (Аида)</Title> </Track> </PlayList>


Слайд 147

<ul> <li> <a href="http://prostopleer.com/tracks/1170056tuNb">Рихард Вагнер — Полёт валькирии — 280</a> </li> <li> <a href="http://prostopleer.com/tracks/264667GXiD">Антонио Вивальди — Времена года. Лето. Шторм — 203</a> </li> <li> <a href="http://prostopleer.com/tracks/35532014SEz">Иоган Бах — Токката и фуга ре-минор — 187</a> </li> <li>Эдвард Григ — В пещере горного короля — 163</li> <li> <a href="http://prostopleer.com/tracks/613982Fj9E">Джузеппе Верди — Триумфальный марш (Аида) — 103</a> </li> </ul>


Слайд 148

Вариант с использованием xsl:apply-templates <?xml version="1.0" encoding="utf-8"?> <!DOCTYPE xsl:stylesheet [ <!ENTITY mdash "&#8212;“> ]> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="xml" indent="yes" omit-xml-declaration="yes"/>   <xsl:template match="PlayList"> <ul> <xsl:apply-templates select="Track"> <xsl:sort select="@Length" data-type="number" order="descending"/> </xsl:apply-templates> </ul> </xsl:template>   <xsl:template match="Track"> <li> <a href="http://prostopleer.com/tracks/{@Id}"> <xsl:apply-templates select="." mode="TrackName" /> </a> </li> </xsl:template> <xsl:template match="Track[not(@Id)]"> <li> <xsl:apply-templates select="." mode="TrackName" /> </li> </xsl:template>   <xsl:template mode="TrackName" match="Track"> <xsl:value-of select="concat(Artist, ' &mdash; ', Title, ' &mdash; ', @Length)"/> </xsl:template> </xsl:stylesheet>


Слайд 149

При использовании элемента xsl:for-each потребовалось добавить ветвление. При использовании элемента xsl:apply-templates — новый шаблон. Если бы шаблон match="PlayList" уже содержал ветвления и логику, то понадобилось бы некоторое время, чтобы разобраться, куда именно нам нужно вставить ветку. Вариант с xsl:apply-templates лишён этого недостатка, поскольку мы лишь декларируем новый шаблон, а не пытаемся внедриться в старые. Использование xsl:for-each имеет ещё одну большую опасность. Если анализируется произвольный участок кода внутри шаблона match="PlayList", то предполагается, что текущий элемент это PlayList, однако xsl:for-each меняет контекст. Например следующий код код: <xsl:apply-templates select="." mode="TrackName" /> Потребуется внимательно присмотреться к контексту, чтобы понять, что select="." на самом деле выбирает текущий Track.


Слайд 150

Шаблон mode="TrackName" match="Track" был добавлен для избежания дублирования кода, отображающего название. Этого не было сделано раньше, так, как не было необходимости. Как только появилось дублирование, то понадобилось вынести общую логику отображения в новый шаблон. Элемент xsl:for-each не плодить сущности. Просто нужно добавить логику отображения внутрь xsl:for-each и всё хорошо работает. Проблемы начинаются в том случае, когда тело цикла разрастается, и приходится проводить изменения xsl:for-each, которые намного сложнее, чем вынесение повторяющегося кода. 


Слайд 151

И наконец, рассмотрим XSLT, которая позволит прослушать все композиции из демонстрационной XML.  <?xml version="1.0" encoding="utf-8"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="xml" indent="yes" omit-xml-declaration="yes"/> <xsl:template match="Track"> <div> <object width="411" height="28"> <param name="movie" value = "http://embed.prostopleer.com/track?id={@Id}"> </param> <embed src="http://embed.prostopleer.com/track?id={@Id}" type = "application/x-shockwave-flash" width="411" height="28"> </embed> </object> </div> </xsl:template> </xsl:stylesheet>


Слайд 152

Результат <div><object width="411" height="28"><param name="movie" value="http://embed.prostopleer.com/track?id=1170056tuNb" /><embed src="http://embed.prostopleer.com/track?id=1170056tuNb" type="application/x-shockwave-flash" width="411" height="28" /></object></div> <div><object width="411" height="28"><param name="movie" value="http://embed.prostopleer.com/track?id=938304vu1E" /><embed src="http://embed.prostopleer.com/track?id=938304vu1E" type="application/x-shockwave-flash" width="411" height="28" /></object></div> <div><object width="411" height="28"><param name="movie" value="http://embed.prostopleer.com/track?id=35532014SEz" /><embed src="http://embed.prostopleer.com/track?id=35532014SEz" type="application/x-shockwave-flash" width="411" height="28" /></object></div> <div><object width="411" height="28"><param name="movie" value="http://embed.prostopleer.com/track?id=264667GXiD" /><embed src="http://embed.prostopleer.com/track?id=264667GXiD" type="application/x-shockwave-flash" width="411" height="28" /></object></div> <div><object width="411" height="28"><param name="movie" value="http://embed.prostopleer.com/track?id=613982Fj9E" /><embed src="http://embed.prostopleer.com/track?id=613982Fj9E" type="application/x-shockwave-flash" width="411" height="28" /></object></div>


Слайд 153

Результат рендеринга


×

HTML:





Ссылка: