XSLT

Автор: Талисов М.Е. Copyright © 2007. Все права защищены.
В данном руководстве рассматривается технология XSLT на простом примере. В качестве платформы для разработки используется J2SE 1.5.
Дата создания: 08.03.07.

Cодержание

  1. 1 Краткое описание технологии XSLT
    1. 1.1 Введение
    2. 1.2 Описание шаблонов
    3. 1.3 Переменные и параметры
    4. 1.4 Функции
  2. 2 Пример XSLT-описания
    1. 2.1 Описание предметной области
    2. 2.2 XSLT-описание
  3. 3 Программное XSLT-преобразование
    1. 3.1 Основные API
    2. 3.2 Пример программы

1 Краткое описание технологии XSLT

1.1 Введение

XSLT (Extensible Stylesheet Language Transformation) – язык для описания процедуры преобразования XML-документов в документы другого вида: XML, HTML и текстовый. Схему преобразования документов можно представить так:

Однако исходный документ можно преобразовать и в другой, формат, отличный от трех приведенных. Для этого нужно использовать технологию XSL-FO (XSL Formatting Objects) и специальные преобразователи для нужных форматов. При этом схема преобразования будет выглядеть примерно так:

XLST-описание выполняется с использованием технологии XML. Таким образом XSLT, также как и язык схем, является XML-языком. Идентификатор пространства имен для этого языка: http://www.w3.org/1999/XSL/Transform (принято использовать префикс xsl:).

Корневым элементом XSLT документа является элемент stylesheet, внутри которого можно использовать следующие дочерние элементы (top-level element):

  • import;
  • include;
  • strip-space;
  • preserv-space;
  • output;
  • key;
  • decimal-format;
  • namespace-alias;
  • attribute-set;
  • variable;
  • param;
  • template.

Эти элементы в теле stylesheet могут располагаться в любом порядке. Кроме того, он может содержать элементы из другого пространства имен (не XSLT) при условии, что полное имя этих элементов содержит идентификатор пространства имен, отличный от null.

Элемент stylesheet имеет обязательный атрибут version, для которого определено значение 1.0.

Элементы, используемые в XSLT документах, но не относящиеся к языку XSLT, зачастую используются для формирования структуры выходного XML или HTML документа, а также внедрения документации.

Элемент include используется для блочного конструирования XSLT документов путем включения одного XSLT документа в состав другого. URI включаемого документа задается атрибутом href. Включение работает на уровне структуры XML-документа, содержащего XSLT описание. При включении в тело включающего документа помещаются дочерние элементы; они замещают элемент include и не влияют на порядок обработки правил преобразования XSLT. Запрещается прямо или косвенно включать самого себя.

Элемент import реализует механизм импорта XSLT документов, который отличается от механизма включения тем, что включенные правила преобразования имеют меньший приоритет, чем правила, содержащиеся в импортирующем документе. URI импортируемого документа указывается атрибутом href. Элементы import, если они используются, должны идти первыми.

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

Элемент output позволяет указать в каком формате будет осуществляться вывод результата XSLT преобразования.

XSLT преобразование определяется как преобразование исходного XML-документа в другой XML-документ. Так как XSLT оперирует древовидной моделью документа, то исходный XML-документ часто называют Source XML Tree, а результат преобразования – Result XML Tree. При этом результат преобразования может быть выведен и в не XML виде.

В XSLT существует три метода вывода: xml, html, text. Соответственно метод вывода задается атрибутом method элемента output. Можно указать одно из трех значений и другие значения, не определенные спецификацией. В этом случае значение атрибута method будет специфично для XML-процессоров.

При отсутствии элемента output метод вывода определяется следующим образом: если результат преобразования имеет единственный дочерний элемент корневого узла, его локальное имя html, а идентификатор пространства имен – null, то метод вывод – html, иначе – XML.

Остальные атрибуты элемента output задают параметры вывода:

  • version – указывает версию для метода вывода: это актуально для методов вывода html и xml. Значения по умолчанию: html – 4.0, xml – 1.0;
  • encoding – указывает имя кодировки, в которой осуществляется вывод. Обязательная поддержка: UTF8, UTF16;
  • media-type указывает mime тип результата вывода: для XML – text/html; для html – text/html; для text – text/plain;
  • doctype-public, doctype-system – указывает соответственно публичный и системный идентификатор для document type declaration, внедряемый в результат вывода (актуальный для методов вывода html и xml);
  • omit-xml-declaration – позволяет указать включать или нет xml-declaration в результат вывода для метода xml: значение по умолчанию – no, если yes, то xml-declaration не включается;
  • cdata-section-elements – актуален для метода xml, позволяет указать список имен элементов, чьи текстовые дочерние узлы должны быть выведены в секции cdata.

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

1.2 Описание шаблонов

Описания шаблонов выполняется элементами template. Узел или множество узлов, к которым применяется шаблон, указывается атрибутом match, значение которого – Xpath выражение. Шаблону может быть назначено имя атрибутом name, что позволяет вызывать его из других шаблонов. В теле шаблона содержится инструкция. Основные инструкции оформляются элементами.

Apply-templates позволяет применить шаблоны к дочерним элементам тех элементов, к которым применим данный шаблон. Ограничить множество дочерних узлов можно атрибутом select.

Существует группа инструкций для создания элементов, атрибутов и текстовых узлов результирующего дерева.

Элементы создаются инструкцией element. Атрибут name (обязательный) – квалифицированное имя, namespace – идентификатор пространства имен, use-attribute-sets – список имен групп атрибутов.

Атрибуты создаются инструкцией attribute. Name – обязательный атрибут, namespace – идентификатор пространства имен.

Текстовые узлы создаются инструкцией text с атрибутом disable-output-escaping. Значение по умолчанию – no. Если указано yes, то происходит обработка esc-последовательностей. Например, «&lt;» не выполняется, то есть для данного примера в результате преобразования будет помещен текстовый узел с содержимым не «<», а с «&lt;».

В теле инструкций element и attribute указывается шаблон, а в теле инструкции text - содержимое создаваемого текстового узла. Инструкции element и attribute используются для создания вычисляемых узлов, то есть узлов, имена которых могут определяться выражением.

Инструкции обработки создаются инструкцией processing-instruction. Атрибут name – имя, атрибут comment – комментарии.

Именованные группы атрибутов, которые можно использовать при создании элементов, создаются с помощью top-level-element, attribute-set (обязательный элемент), name – имя. В теле указывается инструкция attribute.

Генерировать текст выходного документа, обращаясь к элементам и атрибутам входного и используя переменные, можно с помощью инструкции value-of. Атрибут select (обязательный) указывает XPath выражение, результат вычисления которого преобразуется в строку по правилам функции String и на ее основе создается новый текстовый узел. Атрибут disable-output-escaping позволяет отключить обработку esc-последовательностей.

Инструкция number позволяет форматировать числа, которые будут включены в выходной документ. Атрибут value задает XPath выражение, результат вычисления которого преобразуется в число по правилам функции number, которое затем округляется до целого и преобразуется в строку на основе остальных атрибутов функции number. Результат преобразования приводит к созданию нового текстового узла. Если этот атрибут не указан, в качестве исходного значения используется позиция текущего узла. При этом учитываются следующие атрибуты:

  • level – single, multiple, any;
  • from – указывает с какого узла начинается нумерация;
  • count – какие узлы будут пронумерованы;
  • format – формат преобразования числа в строку, значение по умолчанию – 1. Значения этого атрибута расширяют допустимые значения атрибута type элемента OL в HTML

Существует группа инструкций для управления генерацией вывода, такие, как циклы и ветвление.

Для описания циклов используется for-each. Атрибут select указывает множество узлов для циклической обработки в виде XPath выражения.

Для ветвления используется пара инструкций:

  1. if – простое ветвление. Условие, при соблюдении которого производится обработка тела, задается атрибутом test в виде XPath выражения, результат вычисления которого преобразуется к логическому типу по правилам функции boolean.
  2. choose – множественное ветвление. Альтернативы в ее теле описываются инструкциями when, условия для которого задаются атрибутами test, альтернатива по default описывается инструкцией otherwise.

Sort – для сортировки. Ее можно использовать как дочерний элемент в теле инструкции apply-templates и for-each. Выполняет сортировку узлов, к которым применяются инструкции, совместно с которыми она используется. Атрибут order указывает порядок сортировки. Значения: ascending, descending. Data-type – тип данных: text, number, можно указать и другие значения в виде квалифицированного имени, которое поддерживается данной реализацией XSLT процессора. Case-order – используется, если data-type = text. Указывает, какие символы имеют первоочередной порядок: а или А. Значение по умолчанию определяется атрибутом lang, в котором задается язык сортируемого текста, если не указать, то его значение определяется из системных настроек.

Select – задает выражения, которые вычисляются для каждого обрабатываемого узла, результат вычисления преобразуется в строку по правилам функции string и полученное значение используется как ключ сортировки. Default - . , то есть ключ сортировки – строковое значение узла.

1.3 Переменные и параметры

Переменные позволяют связать имя с некоторым значением и затем использовать его в выражении. Для этой же цели существуют и параметры. Различие в том, что значение, связанное с параметром – это значение по умолчанию для параметра, используемого при вызове шаблона.

Переменные могут использоваться как top-level-elements и как инструкции. Описываются элементом variable.

Параметры описываются элементами param и могут выступать лишь как top-level-elements, имена элементов параметра задаются атрибутом name, значение – атрибутом select в виде XPath выражения.

Вызов шаблона, при котором можно использовать параметры, описывается инструкцией call-template. Имя шаблона – атрибут name (обязательный). Параметры указываются инструкцией with-param в теле инструкции call-template. Имя параметра задается атрибутом name (обязательный), а значение – select (Xpath выражение). Параметры в выражениях можно использовать в виде $имя_параметра.

Пример шаблона:

<xsl:template name = "numbered-block"> <xsl:param name = "format">1.</xsl:param> <fo:block> <xsl:numbere format = "$format"/> <xsl:apply-templates/> </fo:block> </xsl:template> Вызов шаблона: <xsl:template match = "0|//0|/|i"> <xsl:call-template name = "numbered-block"> <xsl:with-param name = "format">a.</xsl:with-param> </xsl:call-tempate> </xsl:template>

1.4 Функции

System-property – возвращает значение системного свойства, имя которого указывается в виде квалифицированного имени в качестве параметра. Имена системных свойств: xsl:version – возвращает версию; xsl:vendor – возвращает название компании XSLT производителя; xsl:vendor-url – возвращает ссылку на его сайт.

Generate-id – генерирует строку, которая уникальным образом идентифицирует узел, который в множестве узлов, переданном как параметр, идет первым в документе.

Format-number – преобразует в строку число, указанное первым параметром, в соответствии с форматом, указанным вторым параметром, и с использованием именованного формата (третий параметр), который необязателен. Если же он все же указан, он должен соответствовать именованному формату, описанному элементом decimal-format, который является top-level-element. Формат, указанный вторым аргументом, описывается в том же синтаксисе, который используется классом DecimalFormat из пакета java.text. Имя указывается атрибутом name. Атрибут decimal-separator указывает символ десятичного разделителя (default (.)), grouping-separator – символ разделителя групп (,), zero-digit(0) – символ нуля, infinity (Infinity) – для представления бесконечности, NaN (NaN) – not a number, minus-sign (-) – для представления «-». Влияют на интерпретацию форматной строки: digit (#) – указывает символ, который обозначает цифру; pattern-separator (;) – указывает символ, который обозначает символ-разделитель для «+» и «-» частей формата строки. Эти атрибуты соответствуют get/set методам класса DecimalFormatSymbols.

2 Пример XSLT-описания

2.1 Описание предметной области

Предметная область будет все та же - компьютерный магазин. Её описание можно найти тут.

2.2 XSLT-описание

Рассмотрим XSLT-описание, формирующее HTML-представление XML-документа. Полученный HTML-документ содержит информацию о проданных компьютерах сотрудниками магазина. При этом для каждого сотрудника выводится таблица, содержащая информацию о проданных им компьютерах, цену и дату продажи. В подвале таблицы указана сумма, на которую были проданы данным сотрудником компьютеры.

XSLT-преобразование содержит указание метода вывода - HTML:

<xsl:output method = "html" version = "4.01" media-type = "text/html" encoding = "utf-8" doctype-public = "-//W3C//DTD HTML 4.01 Transitional//EN" doctype-system = http://www.w3.org/TR/html4/loose.dtd />

В XSLT-описании используются именованные параметризованные шаблоны (данный шаблон выводит ссылку на электронный адрес сотрудника):

<xsl:template name = "mailto"> <xsl:param name = "node" select = "."/> <xsl:choose> <xsl:when test = "string-length($node) = 0"> <xsl:text></xsl:text> </xsl:when> <xsl:otherwise> <a> <xsl:attribute name = "href"> mailto:<xsl:value-of select = "$node"/> </xsl:attribute> Отправить письмо </a> </xsl:otherwise> </xsl:choose> </xsl:template>

Для реализации ветвления и цикла используются следующие конструкции:

<xsl:if test = "string(myns:case/myns:epu/@turbo) = 'true'"> (turbo)</xsl:if> <xsl:for-each select = "myns:hdd"> <xsl:value-of select = "@model"/>, <xsl:value-of select = "@size"/> Гб<br/> </xsl:for-each>

Нумерация сотрудников и сортировка компьютеров по цене:

<h2>Сотрудник № <xsl:number value = "position()" format = "1:"/> <xsl:sort data-type = "number" select = "@price" order = "descending"/>

Для форматирования вывода числовой информации используется следующая конструкция:

<xsl:value-of select = "format-number(myns:cpu/@frequency div myns:cpu/@fsb, '0,00', 'ru-RU')"/>

Для подсчета суммы проданных сотрудником компьютеров используется рекурсивный вызов параметризованного шаблона:

<!--Вызов шаблона total с параметром - идентификатором сотрудника--> <xsl:call-template name = "total"> <xsl:with-param name = "empid" select = "$id"/> </xsl:call-template> <xsl:template name = "total"> <!-- Здесь параметр item - это номер системного блока в списке, total - денежная сумма, на которую были проданы компьютеры сотрудником с идентификатором empid --> <xsl:param name = "item" select = "count(/myns:shop/myns:chassis)"/> <xsl:param name = "total" select = "0"/> <xsl:param name = "empid" select = "."/> <xsl:choose> <xsl:when test = "$item = 0"> <xsl:value-of select = "format-number($total, '0,00', 'ru-RU')"/> </xsl:when> <xsl:when test = "$empid != /myns:shop/myns:chassis[$item]/@whosold"> <xsl:call-template name = "total"> <xsl:with-param name = "item" select = "$item - 1"/> <xsl:with-param name = "total" select = "$total"/> <xsl:with-param name = "empid" select = "$empid"/> </xsl:call-template> </xsl:when> <xsl:otherwise> <xsl:call-template name = "total"> <xsl:with-param name = "item" select = "$item - 1"/> <xsl:with-param name = "total" select = "$total + /myns:shop/myns:chassis[$item]/@price"/> <xsl:with-param name = "empid" select = "$empid"/> </xsl:call-template> </xsl:otherwise> </xsl:choose> </xsl:template>

Полный исходный код XSLT-преобразования:

<?xml version = "1.0" encoding = "utf-8"?> <xsl:stylesheet xmlns:xsl = "http://www.w3.org/1999/XSL/Transform" version = "1.0" xmlns:myns = "http://mixa1984.narod.ru/myschema.xsd"> <xsl:output method = "html" version = "4.01" media-type = "text/html" encoding = "utf-8" doctype-public = "-//W3C//DTD HTML 4.01 Transitional//EN" doctype-system = "http://www.w3.org/TR/html4/loose.dtd" /> <xsl:decimal-format name = "ru-RU" decimal-separator = "," grouping-separator = "."/> <xsl:template match = "/myns:shop"> <html> <head> <link href = "chassis.css" rel = "stylesheet" type = "text/css"/> <title>Добро пожаловать в наш компьютерный магазин!</title> </head> <body> <img> <xsl:attribute name = "src"><xsl:value-of select = "myns:image/@src"/></xsl:attribute> <xsl:attribute name = "align">right</xsl:attribute> </img> <br/> <xsl:apply-templates/> <!-- copyright (i3) --><div align="center"><a href="http://www.ucoz.ru/" title="Создать сайт бесплатно"><img style="margin:0;padding:0;border:0;" alt="Hosted by uCoz" src="http://s205.ucoz.net/img/cp/7.gif" width="80" height="15" title="Hosted by uCoz" /></a><br /></div><!-- /copyright --> </body> </html> </xsl:template> <xsl:template match = "myns:contactsShop"> <h1>Контакты магазина: </h1> <xsl:value-of select = "."/> <xsl:call-template name = "mailto"> <xsl:with-param name = "node" select = "myns:email"/> </xsl:call-template> <hr/> <xsl:call-template name = "sale"/> </xsl:template> <xsl:template match = "myns:chassis"/> <xsl:template match = "myns:emplist"/> <xsl:template match = "myns:image"/> <xsl:template name = "sale"> <xsl:for-each select = "../myns:emplist/myns:employee"> <h2>Сотрудник № <xsl:number value = "position()" format = "1:"/> </h2> <div> <strong>ФИО: </strong> <xsl:value-of select = "myns:fio"/> <br/> <strong>Должность: </strong> <xsl:value-of select = "myns:post"/> <br/> <strong>Возраст: </strong> <xsl:value-of select = "myns:age"/> <br/> <strong>Контакты: </strong> <xsl:value-of select = "myns:contactsEmployee"/> <br/> </div> <h2>Список проданных компьютеров: </h2> <xsl:call-template name = "computers"> <xsl:with-param name = "id" select = "@id"/> </xsl:call-template> <hr/> </xsl:for-each> </xsl:template> <xsl:template name = "computers"> <xsl:param name = "id" select = "."/> <table> <thead> <tr> <th>ID</th> <th>Корпус</th> <th>Материнская плата</th> <th>Процессор</th> <th>ОП</th> <th>HDD</th> <th>Коэффициент</th> <th>Привод</th> <th>Видюха</th> <th>Дата продажи</th> <th>Цена</th> </tr> </thead> <tbody> <xsl:for-each select = "../../myns:chassis"> <xsl:sort data-type = "number" select = "@price" order = "descending"/> <xsl:if test = "@whosold = $id"> <tr> <td> <xsl:value-of select = "@id"/> </td> <td> <xsl:value-of select = "myns:case/@title"/>, <xsl:value-of select = "myns:case/@type"/>, <xsl:value-of select = "myns:case/@color"/>, БП: <xsl:value-of select = "myns:case/myns:epu"/> <xsl:if test = "string(myns:case/myns:epu/@turbo) = 'true'"> (turbo)</xsl:if> </td> <td> <xsl:value-of select = "myns:motherboard"/> </td> <td> <xsl:value-of select = "myns:cpu/@model"/>, <xsl:value-of select = "myns:cpu/@frequency"/> МГц, <xsl:value-of select = "myns:cpu/@fsb"/> МГц </td> <td> <xsl:value-of select = "myns:ram/@size"/> Мб </td> <td> <xsl:for-each select = "myns:hdd"> <xsl:value-of select = "@model"/>, <xsl:value-of select = "@size"/> Гб<br/> </xsl:for-each> </td> <td> <xsl:value-of select = "format-number(myns:cpu/@frequency div myns:cpu/@fsb, '0,00', 'ru-RU')" /> </td> <td> <xsl:value-of select = "myns:diskdrive/@type"/>, <xsl:value-of select = "myns:diskdrive/@model"/>, <xsl:value-of select = "myns:diskdrive/@speed"/> </td> <td> <xsl:call-template name = "video"> <xsl:with-param name = "node" select = "myns:videocard"/> </xsl:call-template> </td> <td> <xsl:value-of select = "@dateofsale"/> </td> <td> <xsl:value-of select = "@price"/> руб. </td> </tr> </xsl:if> </xsl:for-each> </tbody> <tfoot> <tr> <th colspan = "10">Сумма продаж:</th> <th> <xsl:call-template name = "total"> <xsl:with-param name = "empid" select = "$id"/> </xsl:call-template> </th> </tr> </tfoot> </table> </xsl:template> <xsl:template name = "mailto"> <xsl:param name = "node" select = "."/> <xsl:choose> <xsl:when test = "string-length($node) = 0"> <xsl:text></xsl:text> </xsl:when> <xsl:otherwise> <a> <xsl:attribute name = "href">mailto:<xsl:value-of select = "$node"/></xsl:attribute> Отправить письмо </a> </xsl:otherwise> </xsl:choose> </xsl:template> <xsl:template name = "video"> <xsl:param name = "node" select = "."/> <xsl:choose> <xsl:when test = "string-length($node/@model) = 0"> <xsl:text>встроенная</xsl:text> </xsl:when> <xsl:otherwise> <xsl:value-of select = "$node/@model"/> </xsl:otherwise> </xsl:choose> </xsl:template> <xsl:template name = "total"> <xsl:param name = "item" select = "count(/myns:shop/myns:chassis)"/> <xsl:param name = "total" select = "0"/> <xsl:param name = "empid" select = "."/> <xsl:choose> <xsl:when test = "$item = 0"> <xsl:value-of select = "format-number($total, '0,00', 'ru-RU')"/> </xsl:when> <xsl:when test = "$empid != /myns:shop/myns:chassis[$item]/@whosold"> <xsl:call-template name = "total"> <xsl:with-param name = "item" select = "$item - 1"/> <xsl:with-param name = "total" select = "$total"/> <xsl:with-param name = "empid" select = "$empid"/> </xsl:call-template> </xsl:when> <xsl:otherwise> <xsl:call-template name = "total"> <xsl:with-param name = "item" select = "$item - 1"/> <xsl:with-param name = "total" select = "$total + /myns:shop/myns:chassis[$item]/@price"/> <xsl:with-param name = "empid" select = "$empid"/> </xsl:call-template> </xsl:otherwise> </xsl:choose> </xsl:template> </xsl:stylesheet>

Теперь о том, как проверить работоспособность этого примера. Для этого вам понадобится (все нижеперечисленные файлы должны находится в одном каталоге):

  1. XML-схема документа;
  2. CSS-описание, чтобы полученный HTML-документ выглядел красиво;
  3. Само XSLT-описание;
  4. Картинка - логотип магазина :)

Теперь вы можете посмотреть результат преобразования (если ваш веб-браузер поддерживает XSLT), открыв XML-документ с тестовыми данными, который содержит ссылку на XSLT-описание.

3 Программное XSLT-преобразование

3.1 Основные API

Для программной трансформации я использую классы из пакета javax.xml.transform JDK 1.5. Трансформация осуществляется объектом типа Transformer, который создается на фабрике TransformerFactory вызовом метода newTransformer, которому, в качестве параметра, указывается источник XSL-документа. Существует также перегруженная версия метода, без параметров, которая не выполняет трансформации.

Для представления источника и результата, используются объекты типа Source и Result. При этом Source и Result – это интерфейсы из пакета javax.xml.transform, для которых предусмотрено три стандартных реализации:

  • DOMSource и DOMResult из пакета javax.xml.transform.dom;
  • SAXSource и SAXResult из пакета javax.xml.transform.sax;
  • StreamSource и StreamResult из пакета javax.xml.transform.stream.

Источник, из которого считывается документ, указывается в элементе Source.

Реализация DOM позволяет представить источник и приемник в виде деревьев. При создании экземпляров DOMSource можно указать вершину дерева. DOMResult – результат преобразования в виде дерева, из которого можно получить корневой узел.

Реализация SAX формирует источник и приемник с использованием SAX-анализатора. При этом возможно связать с объектом типа SAXSource экземпляр XMLReader. При создании SAXSource источник документа можно указать InputSource.

Либо при создании SAXResult, либо при помощи метода setContentHandler можно указать объект обработки событий типа ContentHandler, связанный с содержимым XML-документа, генерируемый трансформером в результате преобразования.

Реализация Stream позволяет использовать в качестве источника и приемника потоки ввода/вывода. Можно использовать в качестве таких потоков любой объект типа:

  • java.io.reader, java.io.writer – текстовые потоки ввода/вывода;
  • java.io.InputStream, java.io.OutputStream – бинарные потоки;
  • java.lang.String – строка;
  • java.io.File – файл.

Обработка ошибок осуществляется объектом типа ErrorListener, который можно прикрепить методом setErrorListener к объекту типа TransformerFactory. В качестве параметра передается TransformerException, из которого можно извлечь информацию о возникшей ошибке. Остановка преобразования - через выброс исключения.

Преобразование выполняется методом transform, который запускает процесс преобразования. В качестве параметров указывается Source и Result (которые могут быть разных видов).

Пустой трансформер может быть использован для сохранения DOM-дерева в файл.

3.2 Пример программы

Программа преобразования использует в качестве источника и результата преобразования типы javax.xml.transform.dom.DOMSource и javax.xml.transform.dom.DOMResult соответственно:

package xslt; //import domparser.*; import java.io.*; import javax.xml.*; import javax.xml.parsers.*; import javax.xml.transform.*; import javax.xml.transform.dom.*; import javax.xml.transform.stream.*; import javax.xml.validation.*; import org.w3c.dom.*; import org.w3c.dom.ls.*; import org.xml.sax.*; import org.xml.sax.helpers.*; public class XSLTTransformer { public static void main(String[] args) { try { TransformerFactory tf = TransformerFactory.newInstance(); tf.setErrorListener(new MyErrorListener()); Transformer transformer = tf.newTransformer(new StreamSource("chassis.xsl")); DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); dbf.setNamespaceAware(true); dbf.setValidating(true); dbf.setAttribute( "http://java.sun.com/xml/jaxp/properties/schemaLanguage", "http://www.w3.org/2001/XMLSchema" ); dbf.setAttribute( "http://java.sun.com/xml/jaxp/properties/schemaSource", "MyShop.xsd" ); DocumentBuilder db = dbf.newDocumentBuilder(); /* MyErrorHandler - класс обработки ошибок парсинга XML-документа, * который находится в пакете domparser (он также используется и в DOM-анализаторе). * Для простоты его можно не прикреплять. */ //db.setErrorHandler(new MyErrorHandler()); Document document = db.newDocument(); //Считываем входной XML-документ в стандартный поток ввода и парсим его: Document xmlDocument = db.parse(System.in); DOMSource xmlSource = new DOMSource(xmlDocument); DOMResult xmlResult = new DOMResult(document); transformer.transform(xmlSource, xmlResult); //Используем DOM Load&Save API DOMImplementationLS domImplementationLS = (DOMImplementationLS) db.getDOMImplementation(); LSSerializer lsSerializer = domImplementationLS.createLSSerializer(); LSOutput lsOutput = domImplementationLS.createLSOutput(); //Записываем полученное DOM-дерево в стандартный поток вывода: lsOutput.setByteStream(System.out); lsSerializer.write(xmlResult.getNode(), lsOutput); } catch(Exception e) { e.printStackTrace(); } } }

Для обработки ошибок этапа преобразования используется специальный класс, реализующий интерфейс javax.xml.transform.ErrorListener, который прикрепляется к объекту типа TransformerFactory:

package xslt; import javax.xml.transform.*; public class MyErrorListener implements ErrorListener { public void warning(TransformerException e) throws TransformerException { System.err.println("WARNING"); System.err.println("Error message: " + e.getMessageAndLocation()); } public void error(TransformerException e) throws TransformerException { System.err.println("ERROR!"); System.err.println("Error message: " + e.getMessageAndLocation()); throw e; } public void fatalError(TransformerException e) throws TransformerException { System.err.println("FATAL ERROR!!!"); System.err.println("Error message: " + e.getMessageAndLocation()); throw e; } }

Команда запуска программы из консоли Windows будет выглядеть примерно так:

java xslt.XSLTTransformer < MyShop.xml > test.html

Естественно, запуск должен происходить из каталога, в котором находится каталог xslt с программой, а также: MyShop.xsd, MyShop.xml, chassis.xsl, chassis.css и logo.gif . При этом каждый HTML-элемент в полученном документе будет содержать такой атрибут: xmlns:myns="http://mixa1984.narod.ru/myschema.xsd". Можно конечно было обойтись и без этого, но в моей работе было такое требование - использовать квалификацию элементов в XML-документе.


В начало страницы

Hosted by uCoz