XML и XSLT (5) Матросов Александр Васильевич Санкт-Петербургский государственный университет XSL-спецификации • XSL – семейство рекомендаций для преобразования и представления XMLдокумента. Состоит из трех частей: – XSL Transformations (XSLT 1.0) • Язык преобразования XML-документа – XML Path Language (XPath 1.0) • Язык выражений, используемых XSLT для доступа или ссылки на части XML-документа. (XPath также используется спецификацией XML Linking) – XSL Formatting Objects (XSL-FO) • XML-словарь задания семантики форматирования 2 Применение XSL-преобразования к XMLдокументу • Отдельные процессоры XSLT – Microsoft XML Parser • msxsl.exe xml-файл xslt-файл -o outputFile – Saxon (Michael Kay) • http://users.iclway.co.uk/mhkay/saxon/ – Oracle XSLT • http://technet.oracle.com/tech/xml/ – Xalan (Apache Project) • http://xml.apache.orj/xalan-j/index.html • Браузеры – Microsoft Internet Explorer • Инструкция по обработке <?xml-stylesheet type="text/xsl" href="planets.xsl"?> • Для других браузеров в соответствии с рекомендациями WWW <?xml-stylesheet type="text/xml" href="planets.xsl"?> 3 XSLT-преобразования в MS IE 6.0 и выше • <?xml version="1.0"?> <?xml-stylesheet type="text/xsl" href="planets.xsl"?> <PLANETS> <PLANET> <NAME>Mercury</NAME> <MASS UNITS="(Earth = 1)">.0553</MASS> <DAY UNITS="days">58.65</DAY> <RADIUS UNITS="miles">1516</RADIUS> <DENSITY UNITS="(Earth = 1)">.983</DENSITY> <DISTANCE UNITS="million miles">43.4</DISTANCE><!--В перигелии--> </PLANET> <PLANET> <NAME>Venus</NAME> <MASS UNITS="(Earth = 1)">.815</MASS> <DAY UNITS="days">116.75</DAY> <RADIUS UNITS="miles">3716</RADIUS> <DENSITY UNITS="(Earth = 1)">.943</DENSITY> <DISTANCE UNITS="million miles">66.8</DISTANCE> </PLANET> <PLANET> <NAME>Earth</NAME> <MASS UNITS="(Earth = 1)">1</MASS> <DAY UNITS="days">1</DAY> <RADIUS UNITS="miles">2107</RADIUS> <DENSITY UNITS="(Earth = 1)">1</DENSITY> <DISTANCE UNITS="million miles">128.4</DISTANCE> </PLANET> </PLANETS> 4 XSLT-преобразования в MS IE 6.0 и выше • <?xml version="1.0"?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/TR/WD-xsl"> <xsl:template match="/PLANETS"> <HTML> <HEAD><TITLE>The Planets Table</TITLE></HEAD> <BODY> <H1>The Planets Table</H1> <TABLE BORDER="2"> <TR> <TD>Name</TD> <TD>Mass</TD> <TD>Radius</TD> <TD>Day</TD> </TR> <xsl:apply-templates/> </TABLE> </BODY> </HTML> </xsl:template> <xsl:template match="PLANET"> <TR> <TD><xsl:value-of select="NAME"/></TD> <TD><xsl:apply-templates select="MASS"/></TD> <TD><xsl:apply-templates select="RADIUS"/></TD> <TD><xsl:apply-templates select="DAY"/></TD> </TR> </xsl:template> </xsl:stylesheet> 5 Выбор имени и массы • <?xml version="1.0"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:strip-space elements="*"/> <xsl:output method="xml" indent="yes"/> <xsl:template match="/"> <xsl:apply-templates/> </xsl:template> <xsl:template match="PLANETS"> <xsl:copy> <xsl:apply-templates/> </xsl:copy> </xsl:template> <xsl:template match="PLANET"> <xsl:copy> <xsl:apply-templates/> </xsl:copy> </xsl:template> <xsl:template match="NAME"> <xsl:copy> <xsl:value-of select="."/> </xsl:copy> </xsl:template> <xsl:template match="MASS"> <xsl:copy> <xsl:value-of select="."/> <xsl:value-of select="@UNITS"/> </xsl:copy> </xsl:template> <xsl:template match="RADIUS"> </xsl:template> <xsl:template match="DAY"> </xsl:template> <xsl:template match="DENSITY"> </xsl:template> <xsl:template match="DISTANCE"> </xsl:template> </xsl:stylesheet> 6 Деревья и узлы (1) • XSLT трактует XML-документ в виде дерева, узлы которого представляют компоненты XML-документа – Корневой узел (представляет весь документ, не путать с корневым элементом, который также называется элементом документа) – Узел атрибута. Содержит значение атрибута после того, как были раскрыты ссылки на сущности и отброшены окружающие символы-разделители. Атрибут элемента рассматривается как его дочерний элемент (отличие от XMLDOM) – Узел комментария. Содержит текст комментария, не содержащий символов <!-- и --> – Узел элемента. Состоит из части документа, заключенной в открывающий и соответствующий ему завершающий теги, или единственный пустой элементтег, например <br/> – Узел пространства имен. Представляет объявление пространства имен, добавляется к каждому элементу, к которому применяется это пространство имен – Узел инструкции обработки. Содержит текст инструкции по обработке, не содержащий символов <? и ?>. – Текстовый узел. Текстовые узлы содержат последовательности символов, то есть текст PCDATA. Текстовые узлы по умолчанию в XSLT подвергаются нормализации, то есть смежные текстовые узлы объединяются. 7 Деревья и узлы (2) • <?xml version="1.0"?> <library> <book> <title> Earthquakes for Lunch </title> <title> Volcanoes for Dinner </title> </book> </library> 8 Деревья и узлы (3) 9 Деревья и узлы (4) 10 Деревья и узлы (5) • Свойства узлов в XSLT-модели документа – Имя. Имя узла; – Строка-значение. Текст узла; – Базовый URI. Базовый URI узла (XML-вариант URL); – Дети. Список дочерних узлов; ноль, если детей нет; – Родитель. Узел-родитель данного узла; – Имеет атрибут. Определяет атрибуты узла элемента, если таковые имеются; – Имеет пространство имен. Определяет узлы пространства имен узла-элемента. 11 Элементы XSLT (1) • Поддерживают большое число атрибутов, и W3C выработал ряд формальных определений типов данных, которые можно присваивать этим атрибутам – NCNameChar Буква, цифра, точка, дефис или символ подчеркивания; – NCName Буква или символ подчеркивания, за которым (необязательно) следуют данные типа NCNameChars. То есть это имя XML, не содержащее двоеточий (Определение имен XML приводится в главе 1.); – QName Полностью определенное (qualified) имя. Оно формируется из префикса (который должен принадлежать к типу NCName), за которым следует двоеточие и локальная часть (которая также должна быть типа NCName); – NameTest Имя (например, «book») или обобщенное имя с символами подстановки (как, например, «book*» или «*»). 12 Элементы XSLT (2) • • Объявление xml <?xml version="1.0"?> Корневой элемент XSLT-документа <xsl:stylesheet version="1.0« xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> . . . </xsl:stylesheet> – id (необязательный). Идентифицирует таблицу стилей. Устанавливается в имя XML; – version (обязательный). Сейчас это значение равно "1.0" • Корневой элемент XSLT-документа может содержать элементы высокого уровня: – – – – – – – – – – – – <xsl:attribute-set> <xsl:decimal-format> <xsl:import> <xsl:include> <xsl:key> <xsl:namespace-alias> <xsl:output> <xsl:param> <xsl:preserve-space> <xsl:strip-space> <xsl:template> <xsl:variable> 13 Элемент <xsl:template> (шаблон) • Используется для выбора одного узла (который может содержать другие узлы) или ряда узлов в исходном документе, и задания способа его(их) преобразования. – match (необязательный). Задает шаблон выбора обрабатываемых узлов. – name (необязательный). Содержит имя шаблона. Принимает значение типа QName – priority (необязательный). Положительное или отрицательное целое или действительное число, задающее приоритет шаблона. Используется, когда один и тот же узел удовлетворяет нескольким шаблонам. – mode (необязательный). Если применяется инструкция <xsl:applytemplates> к множеству узлов, будут использоваться только шаблоны с совпадающим режимом (mode). Принимает значение типа QName. • Каждый элемент <xsl:template> называется правилом (rule). • В общем случае шаблон может содержать ноль или более элементов <xsl:param> за которыми следует его тело, определяющее способ осуществления преобразования. 14 Тело шаблона (1) • Тело состоит из – разобранных символьных данных (PCDATA) – инструкций XSLT • • • • • • • • • • • • • • • • • • <xsl:apply-imports> <xsl:apply-templates> <xsl:attribute> <xsl:call-template> <xsl:choose> <xsl:comment> <xsl:copy> <xsl:copy-of> <xsl:element> <xsl:fallback> <xsl:for-each> <xsl:if> <xsl:message> <xsl:number> <xsl:processing-instruction> <xsl:text> <xsl:value-of> <xsl:variable> 15 Тело шаблона (2) • Тело состоит из (продолжение) – элементов расширения (определяются пользователем) – элементов буквального результата • копируются в результирующее выходное дерево, создаваемое процессором XSLT • их содержимое трактуется как еще одно тело шаблона и разбирается процессором XSLT • <xsl:template match="RADIUS"> <TD> RADIUS: <xsl:value-of select="."> </TD> </xsl:template> • Простое преобразование корневого узла (образец /) <xsl:template match="/"> <HTML> <HEAD> <TITLE>A trivial transformation</TITLE> </HEAD> <BODY> This transformation has replaced the entire document. </BODY> </HTML> </xsl:template> 16 Тело шаблона (3) • Инструкция <xsl:apply-templates> указывает на обработку содержащихся в соответствующем образцу элементе(ах) и его(их) дочерних элементов – select (необязательный). Набор обрабатываемых узлов. Если атрибут опущен, автоматически обрабатываются все дети узла. Устанавливается в выражение; – mode (необязательный). Устанавливает режим обработки. К этому узлу применяются правила шаблона с режимом выбора. Принимает значение типа QName. – может содержать ноль или более элементов <xsl:sort> или <xsl:with-param> • <xsl:template match="/"> <HTML> <xsl:apply-templates> </HTML> </xsl:template> <xsl:template match="PLANETS"> <xsl:apply-templates> </xsl:template> • Добавим <xsl:template match="PLANET"> <P> Planet </P> </xsl:template> 17 Тело шаблона (4) • Получить доступ к значению узла можно при помощи элемента <xsl:value-of> с атрибутами – select (обязательный). Выходное значение. Устанавливается в выражение; – disable-output-escaping (необязательный). Указывает, что символы, такие как > будут отправляться в выходной поток как есть, не изменяясь на &gt. Значения этого атрибута: yes или no. • Изменим в предыдущей версии <xsl:template match="PLANET"> <xsl:value-of select="NAME"> </xsl:template> 18 Выбор метода вывода • Преобразование из XML в другие типы документов выполняет элемент <xsl:output> с атрибутами <xsl:output>: – cdata-section-elements (необязательный). Задает названия тех элементов, чье содержимое вы хотите вывести в виде разделов CDATA. Принимает значение списка QName, разделенных символами-разделителями; – doctype-public (необязательный). Определяет открытый идентификатор, который будет использоваться в объявлении <!DOCTYPE> вывода. Устанавливается в строковое значение; – doctype-system (необязательный). Определяет системный идентификатор, который будет использоваться в объявлении <!DOCTYPE> вывода. – encoding (необязательный). Определяет кодировку символов. Устанавливается в строковое значение; – indent (необязательный). Определяет, будет ли вывод выровнен с отображением структуры вложенности. Устанавливается в «yes» или «no»; – media-type (необязательный). Определяет тип MIME вывода. Устанавливается в строковое значение; – method (необязательный). Определяет формат вывода. Устанавливается в «xml», «html», «text» или допустимое имя типа QName; – omit-xml-declaration (необязательный). Определяет, будет ли включено в вывод объявление XML. Устанавливается в «yes» или «no»; – standalone (необязательный). Определяет, будет ли включено в вывод отдельное объявление, и, если да, устанавливает его значение. Устанавливается в «yes» или «no»; – version (необязательный). Задает версию вывода. Устанавливается в допустимую лексему типа NMToken. 19 Встроенные таблицы стилей • <?xml version="1.0"?> <?xml-stylesheet type="text/xml" href="#stylesheet"?> <!DOCTYPE PLANETS [ <!ELEMENT PLANET (CUSTOMER)*> <!ELEMENT CUSTOMER (NAME,MASS,RADIUS,DAY)> <!ELEMENT NAME (#PCDATA)> <!ELEMENT MASS (#PCDATA)> <!ELEMENT RADIUS (#PCDATA)> <!ELEMENT DAY (#PCDATA)> <!ELEMENT xsl:stylesheet (xsl:template)*> <!ELEMENT xsl:template (#PCDATA)> <!ATTLIST xsl:stylesheet id ID #REQUIRED version CDATA #IMPLIED> ]> <PLANETS> . . . </PLANETS> <xsl:stylesheet version="1.0" id="stylesheet" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> . . . </xsl:stylesheet> 20 Вставка таблицы стилей в другую • • • • • Элемент <xsl:include> включает файл таблицы стилей в другую таблицу стилей Таблица стилей на слайде 17 <xsl:include href="rules.xsl"/> rules.xsl (включаемая таблица хорошо сформированный XML-документ) <?xml version="1.0"?> <xsl:stylesheet version="1.0“ xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:template match="PLANET"> <TR> <TD><xsl:value-of select="NAME"/></TD> <TD><xsl:value-of select="MASS"/></TD> <TD><xsl:value-of select="RADIUS"/></TD> <TD><xsl:value-of select="DAY"/></TD> </TR> </xsl:template> </xsl:stylesheet> Элемент <xsl:import> импортирует файл таблицы стилей в другую таблицу стилей с установкой старшинства правил Элемент <xsl:apply-imports> позволяет добавить в определяемое для элемента правило его форматирование, определенное в импортируемой таблице стилей <xsl:template match="PLANET"> <TR> <TD colspan="4">4/1/2002</TD> <xsl:apply-imports/> </TR> 21 </xsl:template> Шаблоны (подробнее) • • • Когда процессор XSLT находит узел, удовлетворяющий образцу вашего шаблона, этот узел становится контекстным узлом шаблона, то есть все операции производятся над этим узлом Образцы выбора – подмножество языка XPath. Их можно использовать в элементах <xsl:template>, <xsl:key> и <xsl:number>. В частности, в образец можно установить атрибут match у <xsl:template> и <xsl:key>, и атрибуты count и from элемента <xsl:number>. Примеры – "/" выбирает корневой узел; – "*" выбирает узлы элементов (но не всех узлов, как зачастую ошибочно полагают); – "PLANET" выбирает элементы <PLANET> – "PLANET/MASS" выбирает все элементы <MASS>, дочерние для элемента <PLANET> – "//PLANET" выбирает все элементы <PLANET>, производные от корневого узла; – "." выбирает текущий узел (технически это не образец выбора, а выражениеXPath). • Образцы можно также использовать в атрибуте select элементов <xsl:apply-templates>, <xsl:value-of>, <xsl:for-each>, <xsl:copy-of> и <xsl:sort> 22 Шаблоны (подробнее) • • • Простое использование <xsl:apply-templates/> указывает процессору XSLT осуществлять поиск всех шаблонов, выбирающих дочерние узлы контекстного узла. Применять шаблоны в определенном порядке, или иным образом выбрать применяемые шаблоны можно при помощи атрибута select элемента <xsl:apply-templates/>. <xsl:template match="PLANET"> <TR> <TD><xsl:value-of select="NAME"/></TD> <TD><xsl:apply-templates select="MASS"/></TD> <TD><xsl:apply-templates select="RADIUS"/></TD> <TD><xsl:apply-templates select="DAY"/></TD> </TR> </xsl:template> <xsl:template match="MASS"> <xsl:value-of select="."/> </xsl:template> <xsl:template match="RADIUS"> <xsl:value-of select="."/> </xsl:template> <xsl:template match="DAY"> <xsl:value-of select="."/> </xsl:template> 23 Чтение значений атрибутов • Получить доступ к значению атрибута – добавить к имени атрибута префикс @, например: "@src", "@height", "@width". • Выбор любого (всех) атрибута – выражение "@*". • Отобразим единицы (unit) каждого измерения в planets.xml <xsl:template match="MASS"> <xsl:value-of select="."/> <xsl:value-of select="@UNITS"/> </xsl:template> • Вставить текст (пробел) можно при помощи элемента <xsl:text> с одним атрибутом (создается в дереве вывода текстовый узел) – disable-output-escaping – устанавливается в yes, для того чтобы такие символы, как < и > выводились буквально, а не как &lt; и &gt;. По умолчанию установлен в no. • Вставим пробел между значением и единицей измерения <xsl:template match="MASS"> <xsl:value-of select="."/> <xsl:text> </xsl:text> <xsl:value-of select="@UNITS"/> </xsl:template> 24 Создание значений атрибутов (1) • • Можно создать атрибуты с нуля при помощи элемента <xsl:attribute> и присоединить их к элементу в выходном дереве Шаблон значения атрибута – <?xml version="1.0" encoding="UTF-8"?> <PLANETS> <PLANET DAY="58.65 days" RADIUS="1516 miles" MASS=".0553 (Earth = 1)" NAME="Mercury"/> . . . </PLANETS> – Так нельзя! <xsl:template match="PLANET"> <PLANET NAME="<xsl:value-of select="NAME"/>" MASS="<xsl:value-of select="MASS"/>" DAY="<xsl:value-of select="DAY"/>"/> </xsl:template> – Следует <xsl:template match="PLANET"> <PLANET NAME="{NAME}" MASS="{MASS}" RADIUS="{RADIUS}" DAY="{DAY}"/> </xsl:template> или с обращением к значениям атрибутов <xsl:template match="PLANET"> <PLANET NAME="{NAME}" MASS="{MASS} {MASS/@UNITS}" RADIUS="{RADIUS} {RADIUS/@UNITS}" DAY="{DAY} {DAY/@UNITS}"/> </xsl:template> 25 Создание значений атрибутов (2) • В шаблонах значений атрибутов нельзя использовать вложенные фигурные скобки и удваивать, для того чтобы процессор XSLT их пропустил • Шаблоны значений атрибутов всегда работают с контекстным узлом • Шаблоны значений атрибутов можно использовать только в следующих местах: – элементы буквального результата; – элементы расширения; – <xsl:attribute> Здесь можно использовать атрибуты name и namespace – <xsl:element> Здесь можно использовать атрибуты name и namespace – <xsl:number> Здесь можно использовать атрибуты format, lang, letter-value, grouping-separator и grouping-size; – <xsl:processing-instruction> Здесь можно использовать атрибут name – <xsl:sort>. Здесь можно использовать атрибуты lang, datatype, order и case-order 26 Обработка пробельных символов • • • • Из таблицы стилей чистые узлы-разделители не копируются Чистые узлы-разделители – текстовые узлы, содержащие только пробельные символы, – по умолчанию копируются из исходного документа Применить к planets.xml и посмотреть оставшиеся пробельные символы <?xml version="1.0"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="xml"/> <xsl:template match="*"> <xsl:copy> <xsl:apply-templates/> </xsl:copy> </xsl:template> </xsl:stylesheet> Элемент <xsl:strip-space> дает указание процессору XSLT убрать все чистые узлы-разделители, элемент <xsl:preserve-space> дает указание процессору XSLT оставить все чистые узлы-разделители – elements (обязательный). Задает элементы, из которых нужно убрать символы-разделители. Представляет собой список разделенных символамиразделителями NameTest (именами или обобщенными именами с символами подстановок). <xsl:strip-space elements="*"/> 27 Правила по умолчанию в шаблоне • Если для элемента не задано правило, то по умолчанию действует: – – – – – – – • • • • Корневой узел. По умолчанию вызывается <xsl:apply-templates/>; Узлы элементов. По умолчанию вызывается <xsl:apply-templates/>; Узлы атрибутов. Копирует в результирующий документ значение атрибута, однако копирует его как текст, но не как атрибут; Текстовые узлы. Копирует в результирующий документ текст; Узлы комментариев. Нет обработки XSLT, ничего не копируется; Узлы инструкций обработки. Нет обработки XSLT, ничего не копируется; Узлы пространств имен. Нет обработки XSLT, ничего не копируется. Наиболее важное правило по умолчанию применяется к элементам и может быть выражено следующим образом: <xsl:template match="*"> <xsl:apply-templates/> </xsl:template> Правило по умолчанию для текстовых узлов можно выразить следующим образом, где функция XSLT text выбирает текст узла, так что текст текстового узла добавляется в выходной документ: <xsl:template match="text()"> <xsl:value-of select="."/> </xsl:template> инструкции обработки не вставляются в выходной документ, поэтому их правило по умолчанию можно выразить просто при помощи следующей функции XSLT: <xsl:template match="processing-instruction()"/> То же верно для комментариев, их правило по умолчанию может быть выражено при помощи функции XSLT: <xsl:template match="comment()"/> 28 Удаление содержимого • <xsl:template match="RADIUS"> </xsl:template> Элемент <xsl:copy> • Элемент <xsl:copy> позволяет скопировать узел из исходного дерева в выходное. Заметьте, однако, что это поверхностное (shallow) копирование, при котором не копируются потомки и атрибуты узла. У элемента есть один атрибут: – use-attribute-sets. Задает названия наборов атрибутов, которые нужно применить к создаваемому элементу. Принимает значение списка QName, разделенных символами-разделителями. Этот атрибут можно использовать только в том случае, когда контекстный узел является элементом. – Применить таблицу и посмотреть на атрибуты <xsl:template match="*"> <xsl:copy> <xsl:apply-templates/> </xsl:copy> </xsl:template> 29 Элемент <xsl:copy> • Элемент <xsl:copy-of> позволяет осуществлять глубокое копирование узлов, при котором копируется не только узел, но и все его атрибуты и потомки. У этого элемента единственный атрибут: – select (обязательный). Узел или набор копируемых узлов. • <xsl:template match="/"> <xsl:copy-of select="*"/> </xsl:template> • <xsl:template match="MASS"> <xsl:copy-of select="."/> </xsl:template> 30 Элемент <xsl:message> • При помощи элемента <xsl:message> можно дать указание процессору XSLT отобразить сообщение, и, по выбору, прекратить обработку таблицы стилей. У элемента <xsl:message> один атрибут: – terminate (необязательный). Значение «yes» прекращает обработку. По умолчанию установлено «no». • <xsl:template match="DAY"> <xsl:message terminate="yes"> Sorry, DAY information is classified. </xsl:message terminate="yes"> </xsl:template> 31