XSLT-преобразования. DOM XML. Преобразование XML документов. Как работает XSLT

Преобразование формата XML-данных посредством преобразований расширяемого языка таблиц стилей (XSLT)

Перед началом работы

Данное руководство создано для разработчиков, которые хотят использовать XSLT для преобразования XML-данных в другие формы без необходимости программирования на Java™ или других языках.

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

О чем это руководство?

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

В данном руководстве вы изучите:

  • Основы XSLT
  • Использование простых шаблонов
  • Публикацию данных
  • Управление пробелами
  • Основы XPath
  • Функции XPath
  • Циклы и условные операторы
  • Импорт и включение других таблиц стилей
  • Расширение XSLT
  • Переменные XSLT
Начало работы

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

Например, у вас могут быть данные в XML, которые вы хотите опубликовать в Интернете, что означает перевод их в HTML. Конечно, вы могли бы вручную просмотреть документ и сделать в нем необходимые изменения, или может быть, вы подумали о том, чтобы загрузить XML в DOM, а затем вручную создать документ вывода.

Что такое XSLT?

Преобразования расширяемого языка таблиц стилей (XSLT) предоставляют способ для автоматического перевода XML-данных из одной формы в другую. Целевая форма - это обычно другой XML-документ, но не обязательно; вы можете преобразовать XML практически во что угодно, просто создав таблицу стилей XSLT и обработав данные. Если вы хотите изменить результаты, вы просто меняете таблицу стилей и обрабатываете XML заново. Здесь есть дополнительное преимущество, расширяющее возможности непрограммистов, например, дизайнеров, которые могут изменять таблицу стилей и влиять на результаты.

Давайте посмотрим пример.

Поставленная задача

В данном руководстве мы возьмем XML-документ и преобразуем его в XHTML-документ, который можно отобразить как Web-страницу. Входные данные - это просто файл с рецептами (см. листинг 1).

Листинг 1. Основные данные Gush"gosh 1pound hamburger 1pound elbow macaroni 2cups brown sugar 1bag chopped onions 1teaspoon dried dill Brown the hamburger. Add onions and cook until transparent. Add brown sugar and dill. Cook and drain pasta. Combine meat and pasta. A balanced breakfast 1cup cereal 1glass orange juice 1cup milk 2slices toast Combine cereal and milk in bowl. Add all ingredients to table.

Замечание редактора : Эти рецепты –приведены просто для примера, так, как их представляет себе автор. Правильный рецепт для Gush"gosh (полученный от его жены, которая и готовит это блюдо) состоит из 1 фунта (0,454 кг) рубленой говядины, 1 фунта рожков, 1/2 стакана желтого сахара, 1 небольшого пакета (около 300 грамм) мелко нарезанного лука, 1 чайной ложки сушеного укропа и 1 небольшой банки томатной пасты, в которую добавляется желтый сахар.

Конечно, это очень простой пример, поэтому вы не увязнете в деталях самих данных, однако в виде XML-данных можно представить что угодно - от процесса журналирования до финансов.

Наша цель - преобразовать эти данные в XHTML-страницу, которая будет отображать рецепты по отдельности и форматировать их ингредиенты и инструкции по приготовлению (см. листинг 2).

Листинг 2. Результат Recipe Gush"gosh Ingredients:

1 pound hamburger
1 pound elbow macaroni
2 cups brown sugar
1 bag chopped onions
1 teaspoon dried dill

Directions:
  • Brown the hamburger.
  • Add brown sugar and dill.
  • Cook and drain pasta.
  • Combine meat and pasta.
  • A balanced breakfast Ingredients:

    1 cup cereal
    1 glass orange juice
    1 cup milk
    2 slices toast

    Directions:
  • Add all ingredients to table.
  • Вы можете отобразить этот результат в браузере, как показано на рисунке 1.

    Рисунок 1. Результат, отображенный в браузере

    Как уже упоминалось, конечной целью может быть любой формат, не только XHTML, и даже не обязательно XML.

    Давайте начнем с простых преобразований.

    Простая таблица стилей

    Самая простая таблица стилей - это просто XML документ, включающий XSLT-вывод (см. листинг 3).

    Листинг 3. Самая простая таблица стилей Recipe Ingredients:

    Directions:

    Обратите внимание на использование пространства имен xsl . Добавление этого пространства имен говорит процессору, какие элементы связаны с обработкой, а какие должны быть просто выведены. Элементы value-of говорят процессору вставить определенные данные в это место. Какие именно данные вставлять определяется содержимым атрибута select .

    Атрибут select состоит из выражения XPath. Подробнее XPath будет обсуждаться в разделе , однако здесь вы можете видеть, что доступ к элементам "название", "ингредиенты" и "инструкция по приготовлению" происходит через иерархию документа. Мы начинаем с корневого элемента, /recipes , и от него движемся вниз.

    Как выполнить преобразование

    Простейший способ выполнить XML-преобразование - это добавить указание на таблицу стилей в XML и отобразить его в браузере (см. листинг 4).

    Листинг 4. Добавление в XML инструкции по обработке при помощи таблицы стилей Gush"gosh ...

    Эта инструкция по обработке говорит браузеру извлечь таблицу стилей, расположенную в basicstylesheet.xsl, и использовать ее для преобразования XML-данных и вывода результатов. Если вы откроете наш XML-документ в браузере Microsoft® Internet Explorer®, то увидите результат, похожий на рисунок 2.

    Рисунок 2. Извлечение таблицы стилей и преобразование XML-данных

    Однако это не совсем то, что мы хотели получить. Если вы выберете в браузере Вид>Просмотр HTML-кода, то увидите изначальный XML. Чтобы увидеть результат преобразования, необходимо произвести это преобразование и создать выходной файл. Это можно сделать через командную строку, используя Java-код со следующей командой (см. листинг 5):

    Листинг 5. Преобразование документа через командную строку java org.apache.xalan.xslt.Process -IN recipes.xml -XSL basicstylesheet.xsl -out result.html

    Если вы получите исключение ClassNotFoundException , возможно, вам нужно загрузить Apache Xalan (см. "Получить продукты и технологии" в разделе ) и добавить включенные в него JAR-файлы в путь к классам.

    Выполнив преобразование, показанное в листинге 5, вы увидите, что файл result.html содержит следующий код (см. листинг 6).

    Листинг 6. Результаты Recipe Gush"gosh Ingredients:

    1poundhamburger 1poundelbow macaroni 2cupsbrown sugar 1bagchopped onions 1teaspoondried dill

    Directions:

    Brown the hamburger. Add onions and cook until transparent. Add brown sugar and dill. Cook and drain pasta. Combine meat and pasta.

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

    Добавление шаблонов

    От преобразования нет никакой пользы, если оно не приводит данные именно к той форме, которая нам нужна. Чтобы это сделать, нужно уметь использовать шаблоны, чему и посвящен данный раздел.

    Создание шаблонов

    Большинство таблиц стилей не имеют такой простой формы, какую вы только что видели в предыдущем разделе. Вместо этого они разбиваются на группу шаблонов, каждый из которых применяется к определенному типу данных. Давайте переведем нашу таблицу стилей в эту форму (см. листинг 7).

    Листинг 7. Переделанная таблица стилей Recipe Ingredients:

    Directions:

    Здесь информация не изменилась, за исключением того, что процессор смотрит на таблицу стилей и начинает с шаблона, совпадающего с корневым элементом документа, как указано в атрибуте match . Затем он выводит этот шаблон, включая все значения, так же как и раньше. Если вы выполните сейчас преобразование, то должны увидеть точно такие же результаты, как и в .

    Но это не то, что мы хотим. Мы хотим иметь возможность форматировать ингредиенты и инструкции. Для этого мы можем создать отдельные шаблоны для каждого из этих элементов и включить их в таблицу стилей (см. листинг 8).

    Листинг 8. Создание дополнительных шаблонов Recipe Ingredients:

    Directions:

    INGREDIENTS HERE INSTRUCTIONS HERE

    Обратите внимание, что вместо того, чтобы просто вывести элемент value-of , мы теперь указываем таблице стилей применять соответствующие шаблоны к элементам ingredients и instructions. Затем мы создали отдельные шаблоны для этих элементов, задав их в атрибуте match . Добравшись до элемента apply-templates , процессор выбирает все элементы ingredients в документе. Затем он ищет шаблон для ингредиентов, а, найдя его, выводит этот шаблон. То же самое он делает с элементом instructions . Результат должен быть похож на изображенный на рисунке 3.

    Рисунок 3. Применение соответствующих шаблонов к элементам ingredients и instructions

    Так, это уже немного ближе, хотя бы понятно, что здесь два рецепта, однако вы вряд ли захотите объединять ингредиенты и инструкции для всех рецептов. К счастью, эту проблему можно решить лучшей организацией шаблонов.

    Публикация шаблонов

    Чтобы лучше организовать данные, обратим внимание на то, как мы разделяем и публикуем шаблоны. XSLT позволяет обрабатывать информацию итеративным образом. Например, можно поделить информацию на отдельные рецепты, а затем отформатировать инструкции и ингредиенты (см. листинг 9).

    Листинг 9. Выделение рецептов Recipe Ingredients:

    Directions:

    INGREDIENTS HERE INSTRUCTIONS HERE

    В данном случае таблица стилей выводит основную страницу (HTML), а затем просматривает каждый рецепт, выводя название, ингредиенты и инструкции для каждого рецепта. Опять-таки XPath мы будем изучать в разделе , но в данном случае элемент recipe становится контекстным узлом, поэтому атрибуты select относятся к этому узлу так же как файлы к конкретному каталогу в файловой системе. Результат должен быть похож на рисунок 4.

    Рисунок 4. Элемент recipe становится контекстным узлом

    Отлично, формат приблизился к желаемому, однако нам все еще нужно отобразить фактическую информацию. Для этого надо изменить шаблоны ingredients и instructions (см. листинг 10).

    Листинг 10. Работа над шаблонами ingredients и instructions ... Ingredients:

    Directions:
  • Важный момент при публикации шаблонов: вы указали процессору применять подходящие шаблоны к элементу ingredients , однако у нас нет специального шаблона для этого элемента. Если вы примените шаблон к элементу, а самого шаблона не будет, то данные просто не появятся. Но это не наш случай.

    Наоборот, мы воспользовались тем, что когда указали процессору применять подходящие шаблоны к элементу ingredients , он ищет не только элемент ingredients , но и дочерние элементы элемента ingredients . Таким образом, он находит шаблон для ингредиентов, в котором вы выводите количество, единицы измерения, название продукта и разрыв строки.

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

    Результат должен быть похож на рисунок 5.

    Рисунок 5. Создание упорядоченного списка в основном шаблоне рецепта

    Определенно формат приближается к желаемому. Однако если вы посмотрите на вывод, то увидите, что проблема с пробелами все еще существует (см. листинг 11).

    Листинг 11. Недоработанный вывод Recipe Gush"gosh Ingredients:

    1poundhamburger
    1poundelbow macaroni
    2cupsbrown sugar
    1bagchopped onions
    1teaspoondried dill

    Directions:
  • Brown the hamburger.
  • Add onions and cook until transparent.
  • ... Добавление пробелов

    Почему это случилось, если мы включали пробелы в таблицу стилей? Должны они были появиться в выводе? Разумеется, необязательно. Есть способы указать таблице стилей оставлять пробелы - они будут изучены в разделе Организация циклов и импорт - однако в некоторых случаях проще явно добавить текст в вывод (см. листинг 12).

    Листинг 12. Добавление текста ...
    ...

    Тем самым мы позаботились о недостающих пробелах. Точно так же с помощью элемента text , можно добавить в шаблон любой произвольный текст. (Помните, что только текст, а не элементы типа разрыва страницы.) Результатом будет такой вывод, какой нам нужен (см. листинг 13).

    Листинг 13. Окончательный вывод Recipe Gush"gosh Ingredients:

    1 pound hamburger
    1 pound elbow macaroni
    2 cups brown sugar
    1 bag chopped onions
    1 teaspoon dried dill

    Directions:
  • Brown the hamburger.
  • Add onions and cook until transparent.
  • Add brown sugar and dill.
  • Cook and drain pasta.
  • Combine meat and pasta.
  • A balanced breakfastIngredients:

    1 cup cereal
    1 glass orange juice
    1 cup milk
    2 slices toast

    Directions:
  • Combine cereal and milk in bowl.
  • Add all ingredients to table.
  • Результат показан на рисунке 6.

    Рисунок 6. Проблема отсутствующих пробелов решена
    Основы XPath

    Возможность преобразовывать данные в форму, в какой вы желаете их видеть, требует понимания языка маршрутов XML, или XPath, который позволяет контролировать, какие именно данные публикуются и/или отображаются. Данный раздел объясняет основные понятия XPath и показывает, как создавать простые выражения.

    Что такое XPath?

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

    Выражение XPath может выбрать единственный узел или набор узлов, либо вернуть единственное значение, основанное на одном или более узлов в документе. До сих пор мы имели дело с очень простыми выражениями XPath, которые выбирают узел или узлы, спускаясь вниз по иерархической структуре. XPath предоставляет несколько способов для задания групп узлов на основании отношений, таких как родитель-потомок или предок-потомок. В данном руководстве мы изучим все эти отношения, называемые осями .

    Вы также узнаете о некоторых более мощных функциях XPath и о предикатах - это в основном условные утверждения, которые можно добавлять в выражения. Например, в разделе Настройка контекста вы увидите, как выбирать все элементы recipe в документе; предикаты позволяют выбрать только конкретный элемент на основании конкретных критериев.

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

    Давайте начнем с изучения контекста выражения.

    Настройка контекста

    Первым шагом в понимании XPath является понимание того, что полученные результаты в большой степени определяются текущим контекстным узлом. Контекстный узел можно считать своеобразным знаком "ты находишься здесь", от которого можно двигаться в различных направлениях согласно выражению XPath. Например, рассмотрим простую таблицу стилей в листинге 14.

    Листинг 14. Демонстрация контекста

    Здесь есть новый элемент - copy-of . Там, где value-of выводит содержимое элемента, copy-of делает именно то, о чем говорит его название, и выводит фактический узел, на который ссылается атрибут select .

    В данном случае в атрибуте select содержится одно из простейших возможных выражений XPath. Одиночная точка (.) – это ссылка на данный контекстный узел, как в файловой системе, когда вы хотите сослаться на "текущую директорию, вне зависимости от того, что это за директория." Поэтому если вы выполните это преобразование, то получите результат, как в листинге 15.

    Листинг 15. Простейшее преобразование Gush"gosh 1pound hamburger 1pound elbow macaroni 2cups brown sugar 1bag chopped onions 1teaspoon dried dill Brown the hamburger. Add onions and cook until transparent. Add brown sugar and dill. Cook and drain pasta. Combine meat and pasta. ...

    Вы видите, что это просто повторение того же документа; это потому, что контекстный узел, как указано атрибутом шаблона match, - это корень документа, или /. Если вы измените контекстный узел, вывод изменится. Например, вы можете установить контекстный узел на первый рецепт (см. листинг 16).

    Листинг 16. Перемещение контекстного узла

    Теперь, запустив преобразование, вы увидите разницу (см. листинг 17).

    Листинг 17. Результаты Gush"gosh 1pound hamburger 1pound elbow macaroni 2cups brown sugar 1bag chopped onions 1teaspoon dried dill Brown the hamburger. Add onions and cook until transparent. Add brown sugar and dill. Cook and drain pasta. Combine meat and pasta. A balanced breakfast 1cup cereal 1glass orange juice 1cup milk 2slices toast Combine cereal and milk in bowl. Add all ingredients to table.

    Так как мы переместили контекстный узел, вывод изменился. Это важно, когда вы хотите выбрать узел относительно контекстного узла. Например, вы можете выбрать только заголовок рецепта (см. листинг 18).

    Листинг 18. Выбор только заголовка

    Здесь вы выбираете элемент name , расположенный на один уровень ниже, чем текущий контекстный узел, поэтому результат будет как в листинге 19.

    Листинг 19. Результаты Gush"gosh A balanced breakfast

    Мы изучим задание узлов по номеру позже, а пока отметим, что мы можем переместить контекстный узел во второй рецепт (см. листинг 20).

    Листинг 20. Еще одно перемещение контекстного узла

    (Не обращайте внимания на еще один шаблон, он нужен, чтобы не появлялся текст другого рецепта.)

    Мы можем видеть, что результирующее преобразование показывает это изменение контекста (см. листинг 21).

    Листинг 21. Результаты A balanced breakfast Для чего нужны оси

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

    Для начала давайте поговорим о системе обозначений. Мы использовали упрощенную, укороченную форму запроса потомков. В "длинной форме" выражения задаются как child::name вместо./name

    В обоих случаях вы задаете любой узел, который является потомком контекстного узла, а также является элементом name . Вы также можете связать их вместе, как в предыдущем случае, используя /child::recipes/child::recipe вместо /recipes/recipe .

    Потомки

    Возможно, вы недоумеваете, зачем мучаться с длинной формой, если короткая настолько проще. Это не было бы нужно, если бы единственное, что вы могли бы делать - это выбор потомков. Однако эту нотацию также можно использовать для выбора других отношений. Например, выражение XPath descendant::instruction выбирает все элементы instruction, которые являются потомками контекстного узла, а не только дочерние элементы. Кроме того, можно комбинировать инструкции. Например, вы можете выбрать все инструкции второго рецепта: /recipes/recipe/descendant::instruction .

    Одной из разновидностей оси потомков является ось потомок-или-сам-элемент, которая выбирает заданный узел из всех потомков, а также ищет в самом контекстном узле. Например, выражение descendant-or-self::instructions выбирает все узлы instruction в контекстном узле и ниже его. Обычным сокращением для этой оси является двойная косая черта, //. Это означает, что выражения: /recipes/recipe//instructions и //instructions выбирают все инструкции для второго рецепта и все инструкции в документе, соответственно. Этот второй пример очень широко применяется, он удобен, когда вы хотите просто выбрать все элементы определенного типа в документе.

    Атрибуты

    Еще одна общая задача, с которой вы столкнетесь - это необходимость выбрать атрибут для конкретного элемента. Например, вы, возможно, захотите выбрать recipeId для конкретного рецепта. Выражение /recipes/recipe/attribute::recipeId выбирает атрибут recipeId для всех элементов recipe . Эта ось также имеет сокращенную форму: это же выражение можно записать так: /recipes/recipe/@recipeId .

    Родители

    Все, что мы видели до этого, переносило нас вниз по дереву иерархии, но также существует возможность пойти вверх , выбрав предка конкретного узла. Предположим, что контекстным узлом была одна из инструкций, а вы хотите вывести recipeId для текущего рецепта. Вы можете сделать это следующим образом: ./parent::node()/parent::node()/@recipeId .

    Это выражение начинается в текущем узле - instruction -, а затем двигается к предку этого узла - элементу instructions - а затем к предку ТОГО элемента - recipe -, а затем к соответствующему атрибуту. Возможно, вам лучше знакома сокращенная форма: ./../../@recipeId .

    Теперь давайте посмотрим, как задаются некоторые условия.

    Более продвинутые возможности XPath

    В большинстве случаев уже рассмотренных приемов достаточно. Однако нередко встречаются ситуации, требующие большей избирательности. Данный раздел показывает, как использовать предикаты для выбора узлов, основанных на конкретных критериях, и дает представление о некоторых функциях, встроенных в XPath.

    Использование предикатов

    Зачастую требуется не просто любой узел, а конкретный узел, выбранный на основе конкретных условий. Вы ранее уже видели пример, когда использовали выражение /recipes/recipe//instructions . Это на самом деле сокращенная версия выражения /recipes/recipe//instructions , которое означает, что процессор XPath должен пройти через каждый элемент recipes (конечно, такой элемент только один) и для каждого элемента recipes пройти через каждый элемент recipe. Для каждого элемента recipe проверить истинность выражения position() = 2 . (Другими словами, есть ли в списке этот второй рецепт?) Если это предложение, называемое предикатом, истинно, то процессор использует этот узел и продолжает, возвращая любые инструкции.

    С помощью предикатов можно сделать множество вещей. Например, можно вернуть только рецепты, в которых есть название: /recipes/recipe . Это выражение просто проверяет, существует ли элемент name - потомок элемента recipe . Также можно поискать конкретные значения. Например, можно возвращать только элементы, которые называются "A balanced breakfast": //recipe .

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

    Листинг 22. Возвращение только названия первого рецепта //recipe[@recipeId="1"]/name //name]

    В первом выражении сначала мы выбираем все элементы recipe , а затем возвращаем только тот, у которого есть атрибут элемента recipeId , равный 1. Найдя этот узел, мы двигаемся к его дочернему узлу, который называется name, и возвращаем его. Во втором выражении сначала отыскиваются все элементы name , а затем выбирается только тот, у чьего родителя имеется атрибут 1. В любом случае, вы получите один и тот же вывод (см. листинг 23).

    Листинг 23. Вывод Gush"gosh Функции

    XPath также предоставляет ряд функций. Некоторые из них относятся собственно к узлам, - например, те, которые ищут конкретную позицию, - некоторые обрабатывают строки, некоторые, - такие как суммирование, - с числами, некоторые с булевскими значениями.

    Функции, связанные с узлами

    Функции, связанные с узлами, помогают, например, выбрать конкретный узел в зависимости от позиции. Например, вы можете специально запросить последний рецепт: //recipe . Данное выражение выбирает все элементы recipe , а затем возвращает только последний. Вы также можете использовать функции отдельно, вместо того чтобы использовать их как часть предиката. Например, вы можете специально запросить посчитать элементы recipe: count(//recipe) .

    Вы уже видели функцию position() и то, как она работает. Другие функции, связанные с узлами, включают id() , local-name() , namespace-uri() и name() .

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

    Большинство строковых функций предназначено для обработки строк, а не для их проверки, за исключением функции contains() . Функция contains() показывает, является ли данная строка частью большего целого. Это позволит, например, вернуть только узлы, содержащие определенные строки, такие как: //recipe .

    Это выражение возвращает элемент recipe, который содержит в своем элементе name строку "breakfast".

    Функция substring() позволяет выбрать конкретный диапазон символов из строки. Например, выражение: substring(//recipe/name, 1, 5) возвращает A bal .

    Первый аргумент - это полная строка, второй - позиция первого символа, а третий - это длина диапазона.

    Среди прочих строковых функций имеются: concat() , substring-before() , substring-after() , starts-with() и string-length() .

    Числовые функции

    Числовые функции включают функцию number() , которая переводит значение в числовое, чтобы другие функции могли с ним работать. Числовые функции также включают: sum() , floor() , ceiling() и round() . Например, вы можете найти сумму всех значений recipeId при помощи выражения: sum(//recipe/@recipeId) .

    Конечно, особого повода проводить подобное вычисление нет, однако это просто числовое значение, приведенное для примера.

    Функция floor() находит наибольшее целое, которое меньше или равно данному значению, а функция ceiling() находит наименьшее целое, которое больше или равно данному значению. Функция round() работает традиционным образом - округляет (см. листинг 24).

    Листинг 24. Результаты числовых функций floor(42.7) = 42 ceiling(42.7) = 43 round(42.7) = 43

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

    Булевы функции наиболее полезны при работе с условными выражениями, о которых будет рассказано в разделе Условная обработка . Возможно, наиболее полезной функцией является not() , которая может быть использована для определения того, что определенный узел не существует. Например, выражение //recipe возвращает каждый рецепт, содержащий в элементе name строку "breakfast". Но что, если вам нужны все рецепты, кроме завтрака? Можно использовать выражение: //recipe .

    Другие булевы функции включают true() и false() , которые возвращают константы, и boolean() , которая преобразует значение в булево, чтобы его можно было использовать в качестве проверочного.

    Организация циклов и импорт

    Рассмотрим еще два важных аспекта использования таблиц стилей XSLT: создание циклов и импортирование внешних таблиц стилей.

    Организация циклов

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

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

    Листинг 25. Прямое применение стилей с использованием циклов Ingredients:


    Directions:
  • Конструкция цикла очень похожа на структуру for-each , в честь которой она названа. Подобно тезке, каждый экземпляр цикла несет в себе следующее значение списка. В Java-программировании это могло бы быть следующее значение в массиве; здесь это следующий узел в совокупности узлов, возвращенных выражением XPath в атрибуте select . Это означает, что когда вы первый раз выполняете первый цикл, контекстным узлом является первый элемент ingredient . Это позволяет выбрать потомков этого элемента qty, unit и food и добавить их в документ так же, как это было сделано ранее при помощи шаблона. То же самое и с инструкциями, за исключением того, что они просто выводятся напрямую.

    Результаты идентичны тем, что получаются при публикации через шаблоны - почти. Каждый шаблон добавляется к документу как индивидуальная строка, но так как нам необходимо обрабатывать эту информацию как один шаблон, мы теряем множество пробелов, которые видели раньше (см. рисунок 7).

    Рисунок 7. Результаты

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

    Включение и импорт таблиц стилей

    Другая вариация таблиц стилей касается их структуры. До сих пор вся наша информация хранилась в единственной таблице стилей. Однако в некоторых случаях бывает полезно разбить ее на отдельные таблицы стилей. Такая модульность может облегчить поддержку, а также гибкость, позволяя использовать различные таблицы стилей для различных целей. Например, мы можем создать две различные таблицы стилей, одна из которых будет использоваться для ингредиентов (см. листинг 26).

    Листинг 26. Файл ingredients.xsl

    Также можно создать отдельную таблицу стилей для инструкций (см. листинг 27).

    Листинг 27. Файл instructions.xsl
  • Эти шаблоны идентичны шаблонам из действующей таблицы стилей. Их можно добавить к таблице стилей посредством включения (см. листинг 28).

    Листинг 28. Включение таблиц стилей ... Ingredients:

    Directions:

    Хотя здесь мы разместили таблицы стилей в той же директории, что и основную таблицу, делать это не обязательно: атрибут href может содержать любой доступный URL. Обратите внимание, что мы отсылаем процессор на поиск шаблонов для элементов ingredients и instructions , которых нет в этом файле. Однако если обработать таблицу стилей, результат получится точно тот же, как если бы шаблоны были включены напрямую, а не через элемент include (см. рисунок 8).

    Рисунок 8. Результаты

    Элемент include дает тот же результат, как если бы мы добавили содержимое начиная с данной точки. Семантически они идентичны. С другой стороны, есть еще один способ включения информации - импорт.

    XSLT позволяет импортировать таблицу стилей в начало файла. Почему в начало? Потому что целью импорта таблицы стилей является возможность корректировки любых шаблонов, являющихся частью импорта. Например, мы можем импортировать шаблон ingredients и откорректировать его (см. листинг 29).

    Листинг 29. Импорт таблицы стилей ... ...
    • Здесь мы фактически заменили один шаблон двумя, которые заменяют шаблоны в импортированной таблице стилей (см. рисунок 9).

      Рисунок 9. Результаты

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

      Расширение XSLT

      Мы увидели, как сделать XSLT более похожим на программирование. Как насчет добавления к нему фактического программирования? Давайте взглянем на добавление функциональности Java к таблице стилей XSLT.

      Во-первых, следует отметить, что хотя механизм расширения является частью рекомендаций XSLT, рассматриваемая здесь реализация специфична для процессора Xalan XSLT. Основные идеи практически одинаковы для других процессоров, однако для уточнения деталей вам придется сверяться с документацией.

      Элементы расширения

      Расширение XSLT производится с помощью различных методик. Первая - это использование элементов extension . Элемент extension - это элемент в пространстве имен, который указывает на класс Java. Взгляните, например, на следующий элемент extension (см. листинг 30).

      Листинг 30. Использование элемента extension Recipes ...

      Мы создали пространство имен, которое соответствует классу comp.backstop.RecipeScaler , который включает в себя статический метод под названием scaleMessage (см. листинг 31).

      Листинг 31. Класс RecipeScaler package com.backstop; public class RecipeScaler { public static String scaleMessage (org.apache.xalan.extensions.XSLProcessorContext context, org.w3c.dom.Element thisElement){ return "This recipe has been scaled by a factor of " + thisElement.getAttribute("servings") + "."; } }

      Добравшись до элемента, процессор видит префикс пространства имен scaler: и знает, что он обозначен как префикс элемента extension, и таким образом понимает, какой класс обозначен в определении пространства имен. Вызываемый им метод отвечает локальному имени элемента - scaleMessage . Сам метод получает два аргумента, из которых мы фактически используем один. Параметр context ссылается на контекст процессора, который позволяет взглянуть на элементы, относящиеся к элементу extension , однако мы просто займемся самим элементом extension . Так как мы получаем этот элемент как параметр метода, мы можем извлечь значения любых атрибутов, добавленных к этому элементу, таких как servings в данном случае. Текст, возвращенный методом, добавляется к выводу на месте элемента extension .

      Это означает, что если применить таблицу стилей, мы получим результаты, показанные на рисунке 10.

      Рисунок 10. Результаты элемента extension

      Элементы extension могут быть весьма полезны, хотя и несколько сложны в использовании.

      Функции extension

      Еще один способ добавить функциональность при помощи таблиц стилей - это использование функций extension, которые несколько проще реализовывать, чем элементы extension. Например, мы можем создать функцию, которая умножает количество ингредиентов и количество порций (см. листинг 32).

      Листинг 32. Метод scaleIngredient() package com.backstop; public class RecipeScaler { public static String scaleMessage (org.apache.xalan.extensions.XSLProcessorContext context, org.w3c.dom.Element thisElement){ return "This recipe has been scaled by a factor of " + thisElement.getAttribute("servings") + "."; } public static int scaleIngredient(int servings, int original){ return (servings * original); } }

      Добавление этой функции в таблицу стилей идентично добавлению элемента extension, в котором уже есть карта пространства имен для класса (см. листинг 33).

      Листинг 33. Добавление функции extension ...
      ...

      Учтите, что вызов функции включает префикс пространства имен. Как и ранее, процессор видит префикс и знает, что надо выполнить вызов класса RecipeScaler . В результате количество ингредиентов умножается на два (см. рисунок 11).

      Рисунок 11. Использование функции extension

      Хотя данный код и работает, поддерживать его сложно. Давайте посмотрим, как упростить поддержку.

      Программирование XSLT

      Прежде, чем закончить изложение, рассмотрим два аспекта XSLT, которые предоставляют некоторые возможности, характерные для обычных языков программирования.

      Переменные XSLT

      Прекрасно, что мы можем выполнить функцию, но дело кончилось константой, запрятанной в глубине таблицы стилей. Не лучше ли было бы задавать переменные в начале страницы? Конечно, да (см. листинг 34).

      Листинг 34. Задание переменной Recipes ...
      ... Рисунок 12. Использование переменной

      Обратите внимание, что ингредиенты были умножены на количество порций, как и ожидалось. Однако если вы посмотрите внимательнее, то увидите, что элемент extension сработал неверно, приняв переменную за строку, вместо того чтобы использовать значение самой переменной. Это не сбой; спецификация не требует, чтобы процессор что-либо делал со значениями атрибутов перед обработкой элемента extension. Поэтому нам надо как-то избежать этой проблемы.

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

      Первое, что мы можем сделать - это использовать условную обработку, чтобы сообщение отображалось, только если оно нужно. Например, см. листинг 35.

      Листинг 35. Использование элемента if Recipes ...

      Содержимое элемента if , заданное атрибутом test, должно быть равно true (истина). Если это не так, что и произошло в данном случае, вывод не появится вовсе (см. рисунок 13).

      Рисунок 13. Результаты предложения if

      В том виде, в каком оно написано, предложение не имеет особого смысла; если значение больше единицы, элемент extention отобразится со значением "3." Лучше использовать множественный выбор (см. листинг 36).

      Листинг 36. Элемент choose Recipes Recipes have been scaled by an invalid number. Recipes have been scaled for multiple portions. ...

      В данном случае у нас имеется комбинация элементов if-then-else и предложения case из традиционных языков программирования. Элемент choose работает как контейнер, однако элемент when отображает его содержимое, только если его атрибут test равен true (истина). Наконец, если ни один из элементов when не равен true (истина), процессор отображает содержимое элемента otherwise .

      Результат получается такой, какого следует ожидать (см. рисунок 14).

      Рисунок 14. Результат

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

      ЗаключениеПодведение итогов

      Данное руководство позволило продвинуться от начального знакомства с преобразованиями XSLT до составления достаточно сложных таблиц стилей. Сначала вы познакомились с основами таблиц стилей, затем с выражениями XPath - одной из основ XSLT. В последней части данного руководства были рассмотрены некоторые более сложные аспекты таблиц стилей XSLT - переменные, условная обработка и расширения. В результате у вас теперь должно быть достаточно знаний, чтобы делать с таблицами стилей XSLT практически все необходимое - или хотя бы понимать, что еще надо выяснить, если столкнетесь с проблемой.



      Глава 1

      Основы XSLT

      Добро пожаловать в мир языка преобразований расширенной таблицы стилей, XSLT (Extensible Stylesheet Language Transformations). Эта книга послужит вам путеводителем в огромном мире XSLT, который каждую минуту расширяется непредсказуемым образом. Мы хотим, чтобы этот мир стал и вашим миром. Нам нужно охватить весьма большой материал, поскольку в наши дни XSLT используется в очень интересных местах и очень интересными способами. В этой книге вы увидите, как это все работает.

      Собственно XSLT представляет собой средство обработки и форматирования содержимого документов XML. XML уже стал очень популярным, теперь настала очередь XSLT. XML дает вам возможность структурировать данные в документах, a XSLT позволяет работать с содержимым документов XML - оперировать содержимым и создавать другие документы (например, при сортировке XML записей базы данных сотрудников или при сохранении данных в документ HTML, а также при детальном форматировании данных).

      С содержимым документов XML можно работать, написав собственную программу, реализующую интерфейс с приложениями разборщика (parser) XML, однако при этом приходится писать код программы самостоятельно. При помощи XSLT вы можете выполнять задачи подобного же рода, не прибегая к программированию. Вместо того чтобы писать код обработки содержимого документов XML на Java, Visual Basic или С++, можно просто указать при помощи XSLT, что вы хотите сделать, и процессор XSLT сделает все остальное. Именно для этих целей и предназначен XSLT, и в мире XML он выходит на ключевые позиции.

      XSL = XSLT + XSL-FO

      Сам XSLT в действительности является частью более крупной спецификации - расширенного языка таблиц стилей, Extensible Stylesheet Language, или XSL. XSL предназначен для задания точного, до миллиметра, формата документов.

      Форматирующая часть XSL, представляющая гораздо более крупную спецификацию, чем XSLT, основана на специальных форматирующих объектах (formatting objects) - эта часть XSL часто называется XSL-FO (или XSL:FO, или XSLFO). XSL-FO - сложная тема, поскольку задание стилей документов при помощи форматирующих объектов может оказаться весьма запутанным процессом. Фактически XSLT изначально был добавлен в XSL для того, чтобы проще осуществлять преобразование документов XML в документы, основанные на форматирующих объектах XSL-FO.

      Эта книга посвящена XSLT, но рассматривается также и введение в XSL-FO, в том числе способ использования XSLT для преобразования документов в форму XSL-FO; в конце концов, XSLT впервые был представлен для упрощения работы с XSL-FO. В начале данной главы будет приведен обзор как XSLT, так и XSL-FO.

      Краткая историческая справка

      XSL был создан консорциумом World Wide Web Consortium (W3C, www.w3.org) - объединением групп, первоначально возглавлявшимся Тимом Бернерс-Ли (Tim Berners-Lee). W3C - это комитет, выпускающий спецификации, - такие, как спецификация для XSL, используемая в данной книге. Именно спецификации делают XML и XSL тем, чем они являются.

      W3C первоначально, в 1980-х, разработал «дедушку» XML, SGML (Standard Generalized Markup Language, стандартный обобщенный язык разметки), однако он был слишком сложен для того, чтобы завоевать широкую популярность, и в действительности XML (как и HTML) представляет собой упрощенную версию SGML. W3C также создал для работы совместно с SGML язык стилей DSSSL (Document Style Semantics and Specification Language, язык семантики стиля и спецификации документа) - и так же, как XML был произведен от SGML, XSL основан на исходном DSSSL. Как утверждает W3C: «Модель, используемая XSL для отображения документов на экране, базируется на многих годах работы над сложным языком стилей по стандарту ISO, который называется Document Style Semantics and Specification Language (DSSSL)».

      Однако исходная часть XSL, то есть XSL-FO, все равно оказалась не настолько простой, чтобы найти широкое распространение, поэтому XSLT был представлен как средство упрощения преобразования документов XML в форму XSL-FO. Как оказалось, именно XSLT был взят на вооружение, поскольку он представляет собой законченный язык преобразований, позволяющий работать с содержимым документов XML без написания программного кода, преобразовывать эти документы в другие документы XML, формат HTML или другие основанные на текстах форматы. Большой успех XSLT удивил даже W3C.

      Преобразования XSLT-XSL

      XSLT позволяет работать непосредственно с содержимым документов XML. Например, у вас может быть огромный документ XML, содержащий всю бейсбольную статистику за последний сезон, однако вас может интересовать только статистика для питчеров. Чтобы извлечь только эти данные, можно написать программу на Java, Visual Basic или С++, которая будет работать с разборщиками XML. Разборщики представляют собой специальные программные пакеты, читающие документы XML и передающие все данные документа последовательно в ваш код. Затем можно создать новый документ XML, pitchers.xml, содержащий только данные о питчерах.

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

      Помимо преобразования одного документа XML в другой документ XML, можно также преобразовывать документы XML в документы разных типов - таких, как HTML, документы форматированного текста (RTF), документы, использующие XSL-FO и другие. Можно также преобразовать документы XML в иные основанные на XML языки - такие, как MathML, MusicML, VML, XHTML и другие - все это можно осуществить, не прибегая к программированию.

      Во многих случаях язык XSLT может работать аналогично языку баз данных, такому как SQL (Structured Query Language, язык структурированных запросов, - известный язык доступа к базам данных), поскольку он позволяет извлекать требуемые данные из документов XML во многом похоже на то, как инструкция SQL извлекает данные из базы данных. Иногда даже говорят о XSLT как о SQL в Web, и если вы знакомы с SQL, это даст вам некоторое представление о безграничных возможностях XSLT. Например, при помощи таблицы стилей XSLT можно извлечь подмножество данных из документа XML, создать оглавление для большого документа, найти все элементы, удовлетворяющие определенному условию (например, поставщиков с определенным индексом) и т.д. И все это - за один шаг!

      XSL-FO: форматирующие объекты XSL

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

      С другой стороны, из-за излишней сложности XSL-FO не очень популярен, и его нельзя сравнивать с XSLT в этом отношении. Существует не так много программ, поддерживающих XSL-FO, и ни одна из них не реализует достаточно полное приближение к стандарту. Так же как самый распространенный способ применения XSLT - это преобразование XML в HTML, самый распространенный способ применения XSL-FO - преобразование XML в текст в формате PDF (Portable Data Format, переносимый формат данных), используемый в Adobe Acrobat. Пример такого преобразования приведен в конце этой главы, а также в главе 11.

      Спецификации W3C

      W3C выпускает спецификации как для XML, так и для XSL, и именно с ними мы будем работать на протяжении всей книги. Спецификации W3C не называются стандартами, поскольку, по международным соглашениям, стандарты могут создаваться только уполномоченными государством комитетами. Вместо этого W3C начинает с выпуска требований (requirements) для новой спецификации. Требования представляют собой список целей и обзоров спецификации, но сама спецификация на этот момент еще не написана. Далее W3C выпускает спецификации: сначала в виде рабочих проектов (working drafts), которые могут комментировать все заинтересованные лица, затем в виде рекомендаций-кандидатов (candidate recommendations), которые еще могут быть изменены; и, наконец, в виде окончательных рекомендаций (recommendations), которые уже нельзя изменять.

      В следующем списке приведены имеющие отношения к XSLT спецификации W3C, которые мы будем использовать в книге, и адреса, по которым их можно найти:

      Рабочий проект XSLT 1.1 по адресу www.w3.org/TR/xslt11. Это рабочий проект XSLT 1.1, который не будет далее разрабатываться до рекомендации - W3C планирует добавить всю функциональность XSLT 1.1 в XSLT 2.0;

      Требования XSLT 2.0 по адресу www.w3.org/TR/xslt20req. W3C выпустил группу целей для XSLT 2.0, включая дополнительную поддержку схем XML;

      Спецификация XPath 1.0 по адресу www.w3.org/TR/xpath. XPath используется для нахождения и указания на определенные разделы и элементы в документах XML так, чтобы можно было с ними работать;

      Требования XPath 2.0 по адресу www.w3.org/TR/xpath20req. XPath в данный момент обновляется - добавляется дополнительная поддержка XSLT 2.0.

      Версии XSLT

      Спецификации XSLT разрабатывались значительно активнее, чем спецификации для всего XSL. Рекомендация XSLT 1.0 была окончательно принята 16 ноября 1999 г., и эта версия является сегодня основной версией XSLT.

      Затем появился рабочий проект XSLT 1.1 и, хотя первоначально он рассматривался в качестве пролога новой рекомендации, ряд сотрудников W3C начал работать над XSLT 2.0 - и через некоторое время W3C решил прекратить работу над рекомендацией XSLT 1.1. Это означает, что рабочий проект XSLT 1.1 не будет развиваться далее - он навсегда останется в виде рабочего проекта и никогда не станет рекомендацией. Иными словами, не будет выпущено официальной версии 1.1 для XSLT.

      Однако консорциум W3C также утверждает, что он планирует включить большую часть того, что было сделано в рабочем проекте XSLT 1.1, в XSLT 2.0, и поэтому в данной книге я кратко рассмотрю рабочий проект XSLT 1.1. Я обязательно отмечу материал как «только для рабочего проекта XSLT 1.1» при обсуждении нового материала, представленного в рабочем проекте XSLT 1.1.

      Ниже перечислены изменения в XSLT 1.0, сделанные в рабочем проекте XSLT 1.1; заметьте, что этот список приведен здесь только в качестве справочного материала, так как большая часть материала вряд ли пока что-нибудь для вас значит:

      Исключен поддерживаемый в XSLT 1.0 тип данных фрагмента результирующего дерева;

      Метод вывода больше не может произвольно добавлять узлы пространства имен, поскольку процесс установки пространства имен применяется автоматически;

      Была добавлена поддержка для XML Base;

      Теперь поддерживаются несколько выходных документов при помощи элемента

      ;

      Элемент

      теперь может иметь параметры;

      Функции расширения теперь можно определять при помощи функции

      ;

      Функции расширения теперь могут возвращать внешние объекты, не соответствующие никаким типам данных XPath.

      В этой книге рассматривается рекомендация XSLT 1.0. а также рабочий проект XSLT 1.1. В развитие данной темы W3C и выпустил требования для XSLT 2.0, которые также рассматриваются в книге под именем XSLT 2.0. В следующем списке приведен обзор целей XSLT 2.0:

      Добавить дополнительную поддержку для работы с содержимым схемы XML при помощи XSLT;

      Упростить работу со строками;

      Упростить работу с XSLT;

      Улучшить поддержку различных языков;

      Поддерживать повышенную эффективность процессора.

      Хотя XSLT 2.0 еще некоторое время не будет выпущен в окончательном варианте, я рассмотрю все, что о нем известно, при обсуждении имеющих к нему отношение тем. Например, разработанный W3C последователь HTML - это основанный на XML язык XHTML. В XSLT 1.0 и в рабочем проекте XSLT 1.1 нет прямой поддержки преобразований из XML в XHTML, поэтому нам придется создать это преобразование с нуля. Однако такая поддержка входит в состав XSLT 2.0, и я отмечу этот факт при обсуждении XHTML.

      Таким образом, мы рассмотрели краткий обзор тематики; давайте перейдем к работе. XSL предназначен для работы с документами XML, поэтому сначала я хочу рассмотреть структуру документов XML. Вы будете работать с документами XML, но сами таблицы стилей XSL также являются документами XML, что следует помнить при их написании. В этой книге считается, что вы обладаете знаниями и XML, и HTML.

      Документы XML

      Вы должны понимать, как работают документы XML, поэтому проверьте по материалам этого раздела, готовы ли вы к работе. Давайте посмотрим на примере документа XML:

      Вот как работает этот документ: я начал с инструкции обработки XML (все инструкции обработки XML начинаются с ), означающей, что используется XML версии 1.0, единственная определенная сейчас версия, и кодировка символов UTF-8, то есть используется восьмибитная сжатая версия Unicode:

      Welcome to the wild and woolly world of XML.

      Затем я создаю новый тег (tag) с именем

      . Для тега можно использовать любое имя, не обязательно DOCUMENT; необходимо только, чтобы имя начиналось с буквы или символа подчеркивания (_), а последующими символами были буквы, цифры, символы подчеркивания, точки (.) или дефисы (-), но не пробелы. В XML теги всегда начинаются с < и заканчиваются >.

      Документы XML образованы из элементов XML; последние начинаются с открывающего тега, такого как

      (за которым следует содержимое (content) элемента, если оно есть, - например, текст или другие элементы), и завершаются закрывающим тегом, парным тегу открытия (он начинается с символов Welcome to the wild and woolly world of XML

      В этой книге не рассматриваются объявления DTD, но из них видно, что элемент

      - корневой, а элементы и могут, во-первых, находиться внутри него, а во-вторых - содержать текст.

      В документах XML могут присутствовать все виды иерархий, когда один элемент заключен в другой элемент и так далее на много уровней вложенности. Элементам можно также задавать атрибуты, например:

      , где атрибут содержит значение "". При помощи таких атрибутов удобно хранить дополнительные данные об элементах. Еще в документы XML разрешается включать комментарии, поясняющие определенные элементы текстом внутри тегов и .

      Ниже, в листинге 1.1, приведен пример XML-документа

      , в котором эти возможности используются для хранения данных о планетах Меркурии (Mercury), Венере (Venus) и Земле (Earth) - таких как масса, длительность дня, плотность, расстояние от Солнца и т.д. Мы будем работать с этим документом во всей книге, поскольку в нем в компактной форме содержится большая часть возможностей XML, которые могут вам потребоваться. Листинг 1.1. planets.xml .0553 58.65 1516 .983 43.4 .815 116.75 37l6 .943 66.8 1 2107 1 128.4

      Вам нужно также усвоить ряд определений XML, принятых в этой книге:

      CDATA . Простые символьные данные (то есть текст, не содержащий какой-либо разметки);

      ID . Корректное имя XML, которое должно быть уникальным (то есть не использоваться в каких-либо других атрибутах типа ID);

      IDREF . Содержит значение атрибута ID некоторого элемента, как правило, отличного от элемента, с которым связан текущий элемент;

      IDREFS . Несколько идентификаторов (ID) элементов, разделенных пробелами;

      NAME Символ . Буква, разряд, точка, дефис, символ подчеркивания или двоеточие;

      NAME . Имя XML, которое должно начинаться с буквы, символа подчеркивания или двоеточия, за которыми, возможно, следуют дополнительные символы имени;

      NAMES . Список имен, разделенных символом-разделителем;

      NMTOKEN . Лексема, образованная из одной или более букв, цифр, дефисов, символов подчеркивания, двоеточий и точек;

      NMTOKENS . Несколько корректных имен XML в списке, разделенных символом-разделителем;

      NOTATION . Название нотации (которое должно быть объявлено в DTD);

      PCDATA . Разобранные символьные данные. PCDATA не содержит какой-либо разметки, и любые ссылки на сущности уже были в PCDATA раскрыты.

      Теперь у нас есть представление о документах XML, в том числе о том, что такое хорошо сформированный и допустимый документ. Если вы еще не чувствуете себя достаточно уверенно в этом материале, прочитайте другую книгу по этой теме. Вы можете также просмотреть на некоторые ресурсы XML в Web:

      Http://www.w3c.org/xml. Основной web-узел консорциума World Wide Web Consortium, посвященный XML, начальная точка для всех аспектов XML;

      Http://www.w3.org/XML/1999/XML-in-10-points, «XML за 10 шагов» (в действительности только семь) - обзор XML;

      Http://www.w3.org/TR/REC-xml. Официальная рекомендация W3C для XML 1.0, текущая (и единственная) версия. Не слишком просто для чтения,

      Http://www.w3.org/TR/xml-stylesheet/. Все о работе таблиц стилей и XML;

      Http://www.w3.org/TR/REC-xml-names/. Все о пространствах имен XML;

      Http://www.w3.org/XML/Activity.html. Обзор текущей деятельности по XML в W3C;

      Http://www.w3.org/TR/xmlschema-0/, http://www.w3.org/TR/xmlschema-1/ и http://www.w3.org/TR/xmlschema-2/. XML-схемы, альтернатива объявлениям DTD;

      Http://www.w3.org/TR/xlink/. Спецификация XLinks;

      Http://www.w3.org/TR/xptr. Спецификация XPointers;

      Http://www.w3.org/TR/xhtml1/. Спецификация XHTML 1.0;

      Http://www.w3.org/TR/xhtml11/. Спецификация XHTML 1.1;

      Http://www.w3.org/DOM/.W3C Объектная модель документа, DOM (Document Object Model).

      Теперь мы научились создавать документы XML. Каковы они в наглядном виде?

      Как XML выглядит в браузере?

      Можно непосредственно отображать XML-документы при помощи браузера, такого, как Microsoft Internet Explorer версии 5 или более поздней. Например, если сохранить созданный нами XML-документ под именем greeting.xml и открыть его в Internet Explorer, он будет выглядеть так, как показано на рис. 1.1.

      Рис. 1.1. XML-документ в Internet Explorer


      На рис. 1.1 можно видеть документ XML полностью. Нет никакого форматирования, документ XML выглядит в Internet Explorer точно так же, как если бы вы вывели его на печать. (Для отображения экрана, показанного на рис. 1.1, Internet Explorer использовал свою таблицу стилей по умолчанию. Она преобразует XML в формат Dynamic HTML, с которым Internet Explorer умеет работать.) А что, если нам требуется представить данные в другом виде? Допустим, мы захотим представить данные из planets.xml в документе HTML в виде HTML-таблицы?

      Тут-то нам и понадобятся преобразования XSLT. В этой главе мы с ними познакомимся, а в конце главы рассмотрим другую сторону XSL - XSL-FO.

      XSLT-преобразования

      XSLT обладает большими возможностями для оперирования данными в документах XML. Например, при помощи таблицы стилей (stylesheet) XSLT я мог бы отформатировать данные из

      в таблицу HTML. Таблицы стилей содержат правила, установленные для преобразования XML-документа, и большая часть книги посвящена созданию таблиц стилей и объяснению того, как они работают. Вот как выглядит таблица стилей XSLT (листинг 1.2), преобразующая данные из planets.xml в таблицу HTML (мы проанализируем ее в главе 2). Листинг 1.2. planets.xsl xmlns:xsl="http://www.w3.org/1999/XSL/Transform">



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

      (листингом 1.1) и связанной с ним таблицей стилей, (листинг 1.2) - мы будем работать на протяжении всей книги, рассматривая различные возможные преобразования XSLT.

      Как вы свяжете эту таблицу стилей с XML-документом

      ? Как мы увидим в следующей главе, одним из способов это сделать является инструкция обработки XML , использующая два атрибута. Первый атрибут - , который следует установить в «text/xml», чтобы указать, что используется таблица стилей XSLT. (Чтобы использовать таблицы стилей другого типа - каскадирующие таблицы стилей (CSS, cascading stylesheets), обычно использующиеся с HTML - следует задать «text/css».) Второй атрибут - , которому следует присвоить значение URI (вспомните, что XML использует не адреса URL, а идентификаторы URI, Uniform Resource Identifier) таблицы стилей: .0553 58.65 1516 .983 43.4

      Теперь при помощи процессора (processor) XSLT можно применить таблицу

      к и создать новый документ, . Процессор XSLT создает новый файл , который вы можете увидеть на рис. 1.2.

      Рис. 1.2. HTML-документ, созданный процессором XSLT


      Как можно видеть на рис. 1.2, процессор XSLT считывает данные из

      , применяет к ним правила из и создает HTML-таблицу в planets.html. Это наш первый пример XSLT-преобразования.

      Что здесь на самом деле происходит? У нас были XML-документ,

      , и таблица стилей XSLT, . Но каким образом они объединились для создания ? Что нужно для XSLT-преобразования

      Для осуществления XSLT-преобразования, такого как преобразование

      в , необходим XSLT-процессор. Для преобразований документов XML можно использовать XSLT тремя способами:

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

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

      . В частности, Internet Explorer может осуществлять преобразования подобного рода;

      На стороне сервера. Серверная программа, например сервлет Java, может преобразовывать документ автоматически при помощи таблицы стилей и отправлять его клиенту.

      В книге мы рассмотрим все три способа осуществления XSLT-преобразований. Уже в этой главе будет предоставлен обзор всех этих трех различных способов.

      Использование отдельных процессоров XSLT

      Отдельные процессоры XSLT - один из самых распространенных способов провести XSLT-преобразования. Существует весьма много таких процессоров, хотя и не все из них могут обрабатывать все возможные таблицы стилей XSLT. Для того, чтобы использовать процессор XSLT, достаточно запустить его из командной строки (в окне DOS в Windows), задать имя исходного документа XML, имя используемой таблицы стилей и имя документа, который вы хотите создать.

      Ниже приведен список некоторых доступных в Интернете процессоров XSLT в алфавитном порядке - большинство (но не все) из них бесплатны:

      4XSLT , http://Fourthought.com/4Suite/4XSLT. XSLT-процессор для Python;

      EZ/X , http://www.activated.com/products/products.html. Пакет Java одновременно для разбора XML и обработки XSLT;

      iXSLT , http://www.infoteria.com/en/contents/download/index.html Процессор XSLT в командной строке;

      Koala XSL Engine , http://www.inria.fr/koala/XML/xslProcessor. XSLT-процессор для Java, использующий простой API для XML, Simple API for XML (SAX 1.0) и API объектной модели документов, Document Object Model (DOM 1.0) API;

      LotusXSL , http://www.alphaworks.ibm.com/tech/LotusXSL. LotusXSL фирмы IBM реализует XSLT-процессор на Java и может взаимодействовать с интерфейсами API, удовлетворяющими спецификации Document Object Model (DOM) Level 1 Specification. Известный процессор XSLT, но сейчас он вытесняется Xalan 2.0;

      MDC-XSL , http://mdc-xsl.sourceforge.net. Процессор XSLT на С++, его можно использовать как отдельную программу;

      Microsoft XML Parser , http://msdn.microsoft.com/downloads/webtechnology/xml/msxml.asp. Разборщик XML фирмы Microsoft, высокопроизводительный, доступный в виде СОМ-компонента. Его можно использовать для реализации поддержки XSLT в приложениях;

      Sablotron , http://www.gingerall.com/charlie-bin/get/webGA/act/sablotron.act. Sablotron - быстрый, компактный и переносимый процессор XSLT. На настоящий момент поддерживает подмножество рекомендации XSLT. Его можно использовать вместе с С или Perl;

      SAXON , http://users.iclway.co.uk/mhkay/saxon/index.html. Такой процессор XSLT полностью реализует XSLT 1.0 и XPath 1.0, а также ряд расширений упомянутых спецификаций. Обратите внимание на то, что в этом выпуске имеется также поддержка рабочего проекта XSLT 1.1;

      Transformiix , http://www.mozilla.org. Transformiix - XSLT-компонент фирмы Mozilla, в настоящее время частично реализованный в Netscape 6.0;

      Unicorn XSLT processor (UXT) , http://www.unicorn-enterprises.com. Этот процессор XSLT поддерживает XSLT-преобразования и написан на С++;

      Xalan С++ , http://xml.apache.org/xalan-c/index.html. Реализация рекомендаций W3C для XSLT и XML Path Language (XPath). Версия известного процессора Apache Xalan на С++;

      Xalan Java , http://xml.apache.org/xalan-j/index.html. Реализация рекомендаций W3C для XSLT и XML Path Language (XPath) на Java. Версия известного процессора Apache Xalan на Java. Включает также функции расширения для доступа к базам данных на SQL через JDBC и многое другое;

      xesalt , http://www.inlogix.de/products.htmL Этот процессор XSLT существует в виде web-серверного модуля (как для web-сервера Apache, так и для IIS), в виде расширения Netscape 4.x и в виде процессора командной строки;

      XML parser for С , http://technet.oracle.com/tech/xml/parser_c2. Процессор XSLT фирмы Oracle. Поддерживает рекомендацию XSLT 1.0, разработан для использования с С;

      XML parser for Java , http://technet.oracle.com/tech/xml/parser_java2. Процессор XSLT фирмы Oracle. Поддерживает рекомендацию XSLT 1.0, разработан для использования с Java;

      XML parser for PL/SQL , http://technet.oracle.com/tech/xml/parser_plsql. Процессор XSLT фирмы Oracle. Поддерживает рекомендацию XSLT 1.0, разработан для использования с PL/SQL;

      XML:XSLT , http://xmlxslt.sourceforge.net. Этот разборщик XSLT написан на Perl. Частично реализует рекомендацию XSLT;

      Xport , http://www.timelux.lu. Процессор XSLT-преобразования, доступен в виде СОМ-объекта;

      XSL:P , http://www.clc-marketing.com/xslp/download.html. Современный процессор XSLT;

      XT , http://www.jclark.com/xml/xt.html. XT - известная реализация рекомендации XSLT на Java.

      В следующих разделах мы подробно рассмотрим четыре из вышеперечисленных процессоров XSLT: XT, Saxon, XSLT-процессор фирмы Oracle и Xalan. Все они бесплатно доступны в Интернете, и на них можно проверить все приведенные в книге примеры. Если вы хотите изучать примеры, загрузите один из этих процессоров (лучше всего известный и широко используемый - процессор Xalan). Для осуществления XSLT-преобразований я буду пользоваться этими процессорами при дальнейшем изложении.

      Выбранные процессоры основаны на Java, поэтому необходимо, чтобы у вас была установлена Java. Если у вас она еще не установлена, ее можно загрузить бесплатно с web-узла фирмы Sun. Самое последнее издание, на момент написания книги Java 2 версии 1.3 доступно по адресу http://java.sun.com/j2se/1.3. Все, что нужно сделать, - загрузить Java для вашей операционной системы и следовать инструкциям по загрузке на соответствующих страницах.

      Хотя для запуска этих XSLT-процессоров нужна Java, не стоит беспокоиться, если вы не программист - никакого программирования не требуется. В главе 10 будут приведены примеры программирования на Java - для того чтобы продемонстрировать вам, как создавать XSLT-преобразования в коде - но процессоры XT, Saxon, XSLT от Oracle и Xalan можно запускать из командной строки.

      Если вы работаете в Windows, то для вас существует еще более простой способ использовать XT и Saxon - эти процессоры поставляются в виде файлов.ехе (

      и ), которые можно выполнять непосредственно в Windows - и вам совсем не понадобится Java. Этот способ работы также рассмотрен в книге. Использование процессора XSLT на Java

      Для работы с основанным на Java процессором XSLT достаточно загрузить и распаковать (unzip) его - и он готов к работе. Прочитайте, конечно, сопроводительные указания; но, как правило, нужно осуществить только два шага.

      Во-первых, необходимо уведомить Java, как ей найти XSLT-процессор, который хранится в файле архива Java, или JAR (Java Archive). Чтобы сообщить Java о том, где искать JAR-файл, нужно установить переменную окружения classpath в путь этого JAR-файла. Например, в любой версии Windows следует открыть окно DOS и выполнить команду, устанавливающую переменную classpath в путь к JAR-файлу процессора XSLT от Oracle, xmlparserv2.jar, который в этом случае хранится в каталоге

      :

      Теперь можно перейти ко второму этапу - запустить процессор XSLT; при этом будет выполняться класс Java, поддерживающий данный процессор. Для XSLT-процессора Oracle этот класс называется

      . В Windows, например, вы можете перейти в каталог, в котором расположены файлы и , и выполнить класс при помощи Java таким образом: C:\planets>

      При этом файл

      будет преобразован в при помощи . Заметьте: в этом примере предполагается, что файл java.exe, в котором исполняется Java-код, расположен в вашем каталоге Windows. Если его там нет, можно явно задать его месторасположение, каталог Java bin, например (JDK- сокращение от Java Development Kit, a Java 2 версии 1.3 устанавливает себя по умолчанию в каталог ), как в следующей команде: C:\planets>c:\jdk1.3\bin\java oracle.xml.parser.v2.oraxsl planets.xmlplanets.xslplanets.html

      Можно объединить оба этапа (установка переменной

      и запуск процессора XSLT) в один, если вы используете ключ вместе с Java, указывая, какую переменную использовать: C:\planets>c:\jdk1.3\bin\java -ср c:\oraclexml\lib\xmlparserv2.jar oracle.xml.parser.v2.oraxsl planets.xml planets.xsl planets.html

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

      Конечно, все становится намного проще, если вы работаете в Windows и используете скомпилированную версию процессора XT (

      ) либо Saxon (). Ниже приведен пример работы с в Windows для осуществления того же преобразования (здесь предполагается, что расположен в текущем каталоге): C:\planets>

      Мы рассмотрели процесс кратко; теперь я хочу описать четыре процессора XSLT (XT, Saxon, процессор XSLT от Oracle и Xalan) подробно, продемонстрировав, как работать с каждым из них. Обратите внимание на два момента: программное обеспечение, реализующее языки XML и XSL, меняется очень быстро, так что когда вы читаете эти строки, некоторые процессоры уже могут оказаться устаревшими; хотя все процессоры должны поддерживать весь стандартный XSLT, в некоторых случаях они приводят к различным результатам.

      XT Джеймса Кларка

      XT Джеймса Кларка (James Clark) можно загрузить с www.jclark.com/xml/xt.html. Помимо самого процессора XT, вам понадобится разборщик XML, при помощи которого XT будет читать ваш XML-документ. В файлах загрузки XT есть еще файл

      , содержащий разборщик XML Джеймса Кларка; можете впрочем воспользоваться в этих же целях и его разборщиком ХР, загрузив его с адреса www.jclark.com/xml/xp/index.html.

      Я лично предпочитаю использовать разборщик XML Xerces от Apache Project, который расположен по адресу http://xml.apache.org. (Ко времени написания книги текущую версию, Xerces 1.3.0, можно было загрузить с адреса http://xml.apache.org/dist/xerces-j/ в формате zip для UNIX в файле

      и формате для Windows в файле .)

      Сам процессор XT - это приложение Java, включенное в пакет загрузки XT в файле JAR,

      . Для использования и вы должны включить и тот, и другой файлы в переменную , как показано в следующем примере для Windows (соответственно измените места нахождения этих файлов): C:\>set classpath=C:\xerces-1_3_0\xerces.jar;C:\xt\xt.jar

      Затем вы можете воспользоваться классом преобразования XT,

      com.jclark.xsl.sax.Driver.class . Нужно предоставить имя разборщика, которое вы хотите использовать (в данном случае это org.apache.xerces.parsers.SAXParser в архиве ), установив переменную в нужное имя в командной строке. Вот как я использую XT для преобразования в Windows (считая, что файлы и содержатся в каталоге , a расположен в вашем текущем каталоге): C:\planets>java -Dcom.jclark.xsl.sax.parser=org.apache.xerces.parsers.SAXParser com.jclark.xsl.sax.Driver planets.xml planets.xsl planets.html

      Эта строка довольно длинна, и хорошо, что XT также упакован в исполняемый файл Win32

      . Для работы с , однако, необходимо, чтобы на компьютере была установлена виртуальная машина Java от Microsoft, Microsoft Java Virtual Machine (VM), - она входит в поставку Internet Explorer. Вот пример в Windows, осуществляющий то же преобразование, что и предыдущая строка (предполагается, что расположен в текущем каталоге): C:\planets>xt planets.xml planets.xsl planets.html расположен не в текущем каталоге, вы можете задать его месторасположение явно, как в следующем примере (если находится в ): C:\planets>c:\xt\xt planets.xml planets.xsl planets.html Saxon

      Saxon Майкла Кэя (Michael Kay) - один из самых первых процессоров XSLT, его можно бесплатно загрузить с http://users.iclway.co.uk/mhkay/saxon/. Все, что нужно сделать, - это загрузить файл saxon.zip и распаковать архив zip; будет создан требуемый файл Java JAR,

      .

      Для осуществления XSLT-преобразования вначале нужно удостоверится, что

      находится в переменной . Например, в Windows, считая, что находится в , установить переменную можно следующим образом: C:\>set classpath=c:\saxon\saxon.jar

      Теперь для выполнения преобразования можно использовать класс Saxon XSLT,

      com.icl.saxon.StyleSheet.class : C:\planets>java com.icl.saxon.StyleSheet planets.xml planets.xsl

      По умолчанию Saxon выводит результаты на экран - не совсем то, что нужно, если мы хотим создать файл

      . Чтобы создать файл , можно воспользоваться символом перенаправления вывода UNIX или DOS >: C:\planets>java com.icl.saxon.StyleSheet planets.xml planets.xsl > planets.html

      При работе в Windows несложно сразу же вызвать Saxon в виде исполнимой программы Win32, saxon.exe, которая загружается с http://users.iclway.co.uk/mhkay/saxon/. В Windows его можно запустить следующим образом (часть

      задает имя выходного файла): C:\planets>saxon -о planets.html planets.xml planets.xsl Oracle XSLT

      Корпорация Oracle также предоставляет бесплатный процессор XSLT, который можно загрузить с http://technet.oracle.com/tech/xml/, - правда, для этого придется пройти весьма длительную процедуру регистрации. Ко времени написания книги для загрузки процессора XSLT достаточно было щелкнуть на ссылке для XDK для Java http://technet.oracle.com/tech/xml/.

      После распаковки архива zip, загруженного с web-узла Oracle, требуемый JAR-файл (на момент написания книги) будет называться

      . Его можно поместить в вашу переменную в Windows следующим образом: C:\>set classpath=c:\oraclexml\lib\xmlparserv2.jar

      Требуемый класс Java -

      , для преобразования в вы можете использовать его таким образом: C:\planets>java oracle.xml.parser.v2.oraxsl planets.xml planets.xsl planets.html Xalan

      Скорее всего, самый широко используемый отдельный процессор XSLT - это Xalan фирмы Apache Project (Apache - широко распространенный web-сервер). Версию Xalan на Java можно загрузить с http://xml.apache.org/xalan-j/index.html - достаточно щелкнуть на требуемом вам файле архива zip (сейчас это

      для Windows или для UNIX).

      При распаковке загруженного файла вы получите как процессор XSLT,

      , так и разборщик XML, . Оба эти JAR-файла в Windows можно включить в следующим образом (измените пути к файлам в соответствии с вашей системой): C:\>set classpath=c:\xalan-j_2_0_0\bin\xalan.jar;c:\xalan-j_2_0_0\bin\xerces.jar

      Чтобы затем использовать

      для преобразования в , запустите на выполнение класс Java : C:\planets>java org.apache.xalan.xslt.Process -IN planets.xml -XSL planets.xsl -OUT planets.html

      Заметьте, что для указания входного файла используется

      , для указания выходного - , а для указания таблицы стилей XSLT - . Чаще всего мы будем работать именно с процессором Xalan, поэтому ниже приведены дополнительные подробности. Следующий список содержит все лексемы, которые можно использовать с классом , как их выводит сам Xalan: . Использовать в выходных данных только символы возврата каретки (carriage return) - по умолчанию используется CR/LF; . Вывод диагностики времени; . Копировать стек при ошибке; . Использовать формат HTML; ; . Количество пробелов для выравнивания (indent) каждого уровня в выходном дереве - по умолчанию 0; . Использовать в выходных данных только символы перевода строки (linefeed) - по умолчанию используется CR/LF; ; . Устанавливает параметр таблицы стилей; . Режим с минимальным выводом (quiet); . Quiet Pattern Conflicts Warnings, предупреждения конфликтов шаблонов; . Использовать средство форматирования простого текста; . Отслеживать (trace) каждое событие генерации результирующего дерева; . Отслеживать каждое событие выделения; . Отслеживать шаблоны по мере их вызова; . Отслеживать «детей» шаблона по мере их обработки; . Информация о версии; . Проверить входной XML и XSL (по умолчанию проверка отключена); . Использовать средства форматирования XML и добавить заголовок XML; .

      В книге мы рассмотрим все эти процессоры; как уже говорилось, чаше всего я буду использовать Xalan. (Причина в том, что этот процессор стал самым популярным и широко распространенным процессором XSLT.) Разумеется, вы можете использовать любой процессор XSLT, если только он удовлетворяет спецификации XSLT консорциума W3C.

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

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

      Поддержка XSLT включена и в Microsoft Internet Explorer, и в Netscape Navigator. Из этих двух браузеров Internet Explorer обладает гораздо большей поддержкой XSLT, и здесь я буду использовать версию 5.5 этого браузера. О поддержке XSLT в Internet Explorer вы можете прочитать по адресу http://msdn.microsoft.com/xml/XSLGuide/.

      Internet Explorer 5.5 и ранних версий по умолчанию не поддерживает в точности синтаксис XSLT, поэтому нам нужно провести ряд модификаций в файлах

      и . (В следующей главе мы рассмотрим эту тему подробнее. Там приведены адреса, с которых можно загрузить пакеты обновленной поддержки XSLT.) Когда печаталась эта книга появился уже Internet Explorer 6.0. Я установил его и проверил работу; похоже, он поддерживает стандартный синтаксис XSLT (за тем исключением, что все еще требуется использовать тип «» для таблиц стилей - таких как вместо «»). Если вы все еще используете IE 5.5 или более ранний, вам нужно будет провести приведенные здесь и в следующей главе изменения. Если вы хотите избежать этого, используйте IE 6.0: кажется, этот браузер поддерживает полный синтаксис XSLT.

      Для работы с

      в IE (в том числе и версии 6.0) мне пришлось преобразовать атрибут в инструкции обработки из «» в «» (предполагается, что файл расположен в том же каталоге, что и , как указывает атрибут в листинге 1.3). Листинг 1.3. Версия planets.xml для Microsoft Internet Explorer Mercury .0553 58.65 1516 .983 43.4 .815 116.75 3716 .943 66.8 1 2107 1 128.4

      Теперь, если вы используете IE версии 5.5 или более ранней, вы должны также преобразовать таблицу стилей

      (но не для версии 6.0 и старше; в этом случает нужно только изменить атрибут type в инструкции обработки из «» в «»). Мы рассмотрим, как это сделать, в следующей главе, а вот новая версия planets.xsl, которую следует использовать: Листинг 1.4. Версия planets.xsl для Microsoft Internet Explorer




      Теперь можно непосредственно открыть planets.xml в Internet Explorer, как видно на рис. 1.3.

      Рис. 1.3. Осуществление XSLT-преобразования в Internet Explorer


      Хотя таким образом при помощи Internet Explorer можно работать с XSLT, при этом необходимо так изменять таблицу стилей, чтобы она удовлетворяла требованиям Internet Explorer. Поскольку Internet Explorer в текущий момент фактически не поддерживает XSLT, открывая документы XML при навигации, я не буду использовать этот браузер для XSLT-преобразований в книге (кроме специально оговоренных случаев). Для осуществления преобразований я стану использовать процессоры XSLT, такие как Saxon и Xalan, а если результаты будут представляться в формате HTML, то мы будем просматривать их в Internet Explorer.

      Интересно отметить, что существует способ провести настоящие XSLT-преобразования в Internet Explorer, не делая никаких специальных изменений в документах XML или XSL, даже не загружая и не устанавливая последний разборщик MSXML (как обсуждается в главе 2) - однако при этом нужно не осуществлять навигацию XML-документа, а обращаться к встроенному в Internet Explorer процессору XSLT, MSXML3, напрямую при помощи JavaScript.

      Работа с XSLT и JavaScript в Internet Explorer

      Процессор XSLT в Internet Explorer 5.5 является частью разборщика XML MSXML3, и если вы работаете напрямую с MSXML3 при помощи JavaScript, нет необходимости изменять исходные файлы

      и (листинги 1.1 и 1.2), как мы это сделали в предыдущем разделе. Мы посмотрим, как это работает в главе 10, а здесь приведена web-страница , которая при помощи JavaScript и MSXML3 осуществляет преобразование с использованием и отображает результаты (заметьте, что вы можете модифицировать этот документ для использования ваших собственных документов XML и XSLT, не прибегая к написанию кода на JavaScript: достаточно заменить имена и на названия ваших документов XML и XSL) (листинг 1.5). Листинг 1.5. Преобразование в Internet Explorer при помощи JavaScript XSLT Using JavaScript var XMLDocument = new ActiveXObject("MSXML2.DOMDocument.3.0"); var XSLDocument = new ActiveXObject("MSXML2.DOMDocument.3.0"); var HTMLtarget = document.all["targetDIV"]; XMLDocument.validateOnParse = true; XMLDocument.load("planets.xml"); if (XMLDocument.parseError.errorCode != 0) { HTMLtarget.InnerHTML = "Error!"; XSLDocument.validateOnParse = true; XSLDocument.load("planets.xsl"); if (XSLDocument.parseError.errorCode != 0) { HTMLtarget.innerHTML = "Error!"; HTMLtarget.innerHTML = XMLDocument.transformNode(XSLDocument);

      В результате обработки этой web-страницы будет получен тот же результат, что и на рис. 1.3: она напрямую загружает файлы

      и и применяет к ним разборщик MSXML3. Это в точности те же файлы и , с которыми мы работали на протяжении этой главы, - в них нет изменений, необходимых при рассмотрении предыдущей темы, в которой мы непосредственно просматривали в Internet Explorer. Дополнительная информация приведена в главе 10.

      ИСПОЛЬЗОВАНИЕ VBSCRIPT

      Если вам больше нравится VBScript, попробуйте использовать этот язык сценариев Internet Explorer: можно достичь таких же результатов.

      XSLT-преобразования на web-серверах

      Можно осуществлять XSLT-преобразования на web-сервере - так чтобы XML-документ был преобразован до того, как web-сервер отправит его браузеру. Здесь самое распространенное преобразование - это преобразование документа XML в HTML, но преобразования XML-XML на сервере также становятся все более и более распространенными.

      В отличие от остальных XSLT-преобразований, рассмотренных до сих пор в этой главе, при проведении XSLT-преобразований на web-сервере обычно необходимо прибегнуть к программированию. Существует три распространенных способа выполнять XSLT-преобразования на web-серверах: используя сервлеты Java, Java Server Pages (JSP) и Active Server Pages (ASP). В главе 10 мы подробно исследуем все эти три способа. Некоторые процессоры XSLT можно настроить для использования на web-серверах - вот начальный список:

      AXSL , www.javalobby.org/axsl.html. AXSL - серверный инструмент, преобразующий XML в HTML при помощи XSLT;

      Microsoft XML Parser , http://msdn.microsoft.com/downloads/webtechnology/xml/msxml.asp. MSXML3 обеспечивает безопасный доступ к серверу по протоколу HTTP для работы с ASP;

      mod_xslt , http://modxslt.userworld.com. Простой модуль web-сервера Apache, использующий XSLT для получения содержимого XML. Для обработки XSLT используется процессор Sablotron;

      PXSLServlet , www.pault.com/Pxsl При помощи этого сервлета можно преобразовать XML в HTML с использованием XSLT. Он также позволяет читать и записывать данные в базу данных на основе SQL (через JDBC);

      xesalt , www.inlogix.de/products.html. Этот процессор XSLT существует в виде модуля для web-серверов Apache и IIS;

      XML Enabler , www.alphaworks.ibm.com/tech/xmlenabler. XML Enabler позволяет отправлять запросы сервлету, а при ответе сервлета XML Enabler может отформатировать данные при помощи различных таблиц стилей XSLT;

      XT , может быть использован как сервлет Java. Ему требуется сервлет-машина (servlet engine), реализующая, по крайней мере, версию 2.1 Java Servlet API. Класс-сервлет Java называется com.jclark.xsi.sax.XSLServlet.

      Следующий пример демонстрирует страницу JSP, активизирующую на web-сервере процессор Xalan. Xalan преобразует

      в при помощи таблицы стилей . В коде затем считывается файл и отправляется обратно от web-сервера в браузер: XSLTProcessor processor = XSLTProcessorFactory.getProcessor(); processor.process(new XSLTInputSource("planets.xml"), new XSLTInputSource("planets.xsl"), new XSLTResultTarget("planets.html")); FileReader filereader = new FileReader("planets.html"); BufferedReader bufferedreader = new BufferedReader(filereader); while((instring = bufferedreader.readLine()) != null) { %>

      Результат можно увидеть на рис. 1.4: там изображен файл planets.html, отправленный в Internet Explorer web-сервером, на котором выполняется JSP. В главе 10 приведена дополнительная информация об использовании сервлетов Java, JSP и ASP для XSLT-преобразований на стороне сервера.

      Рис. 1.4. Преобразование XML на web-сервере


      Мы рассмотрели, как выполнить XSLT-преобразования при помощи отдельных процессоров XSLT в браузере Internet Explorer и на web-серверах. Однако единственное преобразование, которое мы до сих пор сделали, - это преобразование XML в HTML. Хотя сейчас это наиболее популярное преобразование, преобразования из XML в XML также становятся все более распространенными.

      Преобразования из XML в XML

      Преобразования XML-XML иногда рассматриваются как SQL для Интернета, поскольку они позволяют оперировать запросами к базе данных в XML-документах. Ниже приведен пример. Используемый нами файл

      содержит достаточно много данных о каждой планете: .0553 58.65 1516 .983 43.4 .815 116.75 3716 .943 66.8

      Что, если нам нужно только подмножество этих данных - например, имя и масса каждой планеты? В терминах баз данных

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

      В листинге 1.6 приведена новая версия файла

      , осуществляющая требуемое преобразование: выбираются только имя и масса каждой планеты, которые отправляются в выходной документ. В особенности обратите внимание на то, что мы осуществляем преобразование XML-XML, поэтому я использую элемент , атрибут которого установлен в «xml» (фактически тип выходных данных обычно и есть XML, но если процессор XSLT видит тег , он обычно по умолчанию генерирует HTML). Листинг 1.6. Выбор только имени и массы xmlns:xsl="http://www.w3.org/1999/XSL/Transform">



      к , используя Xalan, чтобы создать новый документ XML, : C:\planets>java org.apache.xalan.xslt.Process -IN planets.xml -XSL planets.xsl -OUT new.xml

      Вот как выглядит результирующий документ XML,

      : .0553(Earth = 1)

      Отметьте, что этот файл выглядит во многом похоже на исходный файл

      , за тем исключением, что каждый элемент содержит только элементы и . Таким образом, мы смогли получить подмножество данных первоначального документа XML.

      Конечно, можно проводить любое число такого рода преобразований XML-XML. Можно обрабатывать данные в документе XML для создания совершенно новых XML-документов. Например, можно взять XML-документ с именами студентов и их отметками и создать новый документ, отображающий средние оценки. В XSLT есть много встроенных функций, позволяющих работать с данными подобным образом, - мы познакомимся с ними в главе 8.

      В дополнение следует сказать, что многие программы используют XML для обмена данными в Интернете, и, так как обычно они форматируют свои документы XML по-разному, еще одним популярным способом использования преобразований XML-XML в Интернете является преобразование XML из формата, используемого одной программой, в формат другой программы.

      Преобразования из XML в XHTML

      Хотя во многих книгах рассматриваются исключительно преобразования из XML в HTML, правда состоит в том, что консорциум W3C этому не очень-то рад. Консорциум пытался сместить акцент с HTML (который они первоначально стандартизировали) на свою новую спецификацию, XHTML, представляющую собой совместимую с XML переработку HTML. Документы XHTML являются также хорошо сформированными допустимыми документами XML, поэтому преобразование из XML в XHTML в действительности есть преобразование из XML в специальный вид XML.

      Хотя W3C активно продвигает XHTML, этот формат еще не стал широко распространенным. Поэтому в данной книге я в основном рассматриваю HTML; но поскольку W3C утверждает, что следует использовать XHTML, я кратко рассмотрю эту тему здесь и в главе 6. Если вы хотите узнать больше о XHTML, прочитайте рекомендацию W3C XHTML 1.0 по адресу www.w3.org/TR/xhtml1/, а также рекомендацию XHTML 1.1 по адресу www.w3.org/TR/xhtml11/.

      Пусть W3C и утверждает, что XML следует преобразовывать в XHTML, а не в HTML, я не видел ни одного работающего примера на их web-узле. Представленные ими примеры на самом деле не генерируют допустимых документов XHTML. Тем не менее, поддержка преобразований XML-XHTML предположительно будет встроена в XSLT 2.0, и желаемое W3C явление, вероятно, нас вскоре ждет.

      Более подробно мы рассмотрим этот тип преобразования в главе 6, а здесь я приведу рабочую версию таблицы

      , которая создает допустимую XHTML-версию (листинг 1.7). Заметьте, что на этот раз в элементе нужно использовать атрибут , и хотя это корректный код XSLT, не все процессоры XSLT смогут его обработать. Листинг 1.7. Преобразование XML-XHTML xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> doctype-system="http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd" doctype-public="-//W3C//DTD XHTML 1.0 Transitional//EN" indent="yes"/>




      Я преобразую

      в допустимый документ XHTML, , используя этот новый вариант и процессор XSLT XT. Сначала нужно корректно установить переменную : С:\>set classpath=c:xerces\xerces-1_3_0\xerces.jar;с:\xt\xt.jar;

      Затем я провожу преобразование:

      C:\planets>java -Dcom.jclark.xsl.sax.parser=org.apache.xerces.parsers.SAXParser.com.jclark xsl.sax.Driver planets.xml planets.xsl planets.html

      В результате будет получен файл XHTML,

      :

      Этот документ,

      , действительно является хорошо сформированным и допустимым документом формата XHTML 1.0 (самый популярный вид XHTML) в соответствии с программой проверки допустимости HTML и XHTML консорциума W3C. Средство проверки HTML/XHTML можно найти в Интернете по адресу http://validator.w3.org/file-upload.html. В главе 6 представлена дополнительная информация о преобразованиях XML-XHTML.

      К настоящему моменту мы провели обзор работы XSLT, рассмотрев преобразования из XML в HTML, XML и XHTML. Далее в книге мы познакомимся с такими преобразованиями XSLT, как преобразования из XML в RTF (форматированный текст, Rich Text Format), в простой текст, XSL-FO, JavaScript, в базы данных на основе SQL, а также и другие. Кроме того, существует много дополнительного материала по XSLT, о котором вам следует знать, и теперь мы освоимся в разнообразных видах ресурсов XSLT, которые можно найти в Интернете.

      Ресурсы XSLT

      В Интернете можно найти огромное количество нужных нам сведений. Имейте в виду, что все приведенные далее адреса URL легко могут измениться; списки будут актуальны столь долго, сколько этого будут хотеть люди, занимающиеся поддержкой перечисленных web-узлов.

      Спецификации, руководства и примеры XSLT

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

      Www.w3.org/Style/XSL/. Основная страница W3C по XSL;

      Www.w3.org/TR/xslt. Спецификация XSLT 1.0;

      Www.w3.org/TR/xslt11. Рабочий проект XSLT 1.1, упрощающий работу с расширениями XSLT и добавляющий поддержку рекомендации W3C XBase;

      Www.w3.org/TR/xslt20req. Требования XSLT 2.0, в которых приводится обзор XSLT 2.0, включающий дополнительную поддержку схем XML;

      Www.w3.org/TR/xsl/. Форматирующие объекты XSL;

      Www.w3.org/Style/2000/xsl-charter.html. Цели комитета XSL;

      Www.w3.org/TR/xpath20req. Требования XPath, в которых приводится обзор XPath 2.0, включающего дополнительную поддержку XSLT 2.0;

      Http://lists.w3.org/Archives/Public/www-xml-stylesheet-comments/. Список таблиц стилей XML консорциума W3C.

      Многие руководства по XSLT и примеры доступны также и из других источников - вот начальный список:

      Http://http.cs.berkeley.edu/~wilensky/CS294/xsl-examples.html. Ряд примеров по XSLT;

      Http://msdn.microsoft.com/xml/reference/xsl/Examples.asp. Примеры шаблонов XSLT, используемых в совпадающих элементах;

      Http://msdn.microsoft.com/xml/XSLGuide/xsl-overview.asp. Начальное описание работы с XSLT;

      Www.lists.ic.ac.uk/hypermail/xml-dev/xml-dev-Nov-1999/0371.html. Руководство по XSLT в виде презентации PowerPoint;

      Www.mulberrytech.com/xsl/xsl-list/. Открытый список, посвященный обсуждению XSL;

      Www.nwalsh.com/docs/tutorials/xsl/xsl/slides.html. Руководство по XSLT;

      Www.oasis-open.org/cover/xsl.html. Описание текущих событий вокруг XSLT;

      Www.w3.org/Style/Activity. Внушительный список страниц, посвященных таблицам стилей W3C;

      Www.xml101.com/xsl/. Полноценный набор справочников по XSLT;

      Www.xslinfo.com. Полезный набор ресурсов по XSLT, собранных Джеймсом Таубером (James Tauber);

      Www.zvon.org/xxl/XSLTutorial/Books/Bookl/bookInOne.html. Справочники по XSLT, XPath, XML, WML и другим языкам.

      Мне известна однако только одна группа новостей Usenet по XSLT, и она поддерживается Microsoft - microsoft.public.xsl. Со временем появятся и другие. Для вас может также представлять интерес список почтовой рассылки по XSL - www.mulberrytech.com/xsl/xsl-list.

      Помимо спецификаций, руководств и примеров W3C, в Интернете можно найти большое число редакторов создания таблиц стилей XSLT.

      Редакторы XSLT

      Для создания используемых в книге документов XML и XSL достаточно обычного текстового редактора, такого как vi, emacs, pico, Windows Notepad или Windows WordPad. По умолчанию предполагается, что документы XML и XSL должны быть написаны в Unicode, хотя на практике их можно создавать и в ASCII, и практически все документы до сих пор были написаны именно в ASCII. Следите только за тем, чтобы при создании документа сохранять его в формате простого текста вашего редактора.

      РАБОТА С WORDPAD

      У текстовых редакторов Windows, таких как WordPad, есть раздражающая особенность - если они не узнают данное вами файлу расширение, они добавляют к имени файла расширение.txt. Для файлов.xml и.xsl это не проблема, поскольку WordPad понимает эти расширения, но если вы попытаетесь сохранить документы, созданные при работе над книгой, с расширением, не распознаваемым WordPad, ко всем ним редактор добавит расширение.txt. Чтобы этого не происходило, при сохранении документа заключайте имя файла в кавычки: "file.abc".

      Будет, однако, намного проще использовать настоящий редактор XML, специально предназначенный для обработки XML-документов. Вот список программ редактирования документов XML:

      Adobe FrameMaker , www.adobe.com. Adobe представляет прекрасный, но дорогой редактор FrameMaker с поддержкой XML;

      XML Pro , www.vervet.com/. Дорогой, но мощный редактор XML;

      XML Writer , на диске, XMLWriter http://xmlwriter.net/. Выделение ключевых слов цветом, удобный интерфейс;

      XML Notepad , msdn.microsoft.com/xml/notepad/intro.asp. Бесплатный редактор XML от Microsoft, немного неудобный в работе;

      eNotepad , www.edisys.com/Products/eNotepad/enotepad.asp. Аналог WordPad, имеющий хорошие средства работы с XML и удобный пользовательский интерфейс;

      XMetal from SoftQuad , www.xmetal.com. Дорогой, но очень мощный редактор XML, любимый редактор многих авторов;

      XML Spy , www.xmlspy.com/. Имеет хороший пользовательский интерфейс и прост в работе;

      Arbortext"s Epic , www.arbortext.com/. Мощный редактор, дорогой, обладает богатыми возможностями настройки.

      Редактор XML Spy изображен на рис. 1.5, XML Writer - на рис. 1.6, a XML Notepad - на рис. 1.7.


      Рис. 1.5. Редактирование XML в XML Spy



      Рис. 1.6. Редактирование XML в XML Writer



      Рис. 1.7. Редактирование XML в XML Notepad


      Существуют и специальные редакторы XSLT. Вот начальный список:

      Http://lists.w3.org/Archives/Public/xsl-editors/. Список обсуждения редакторов XSL на web-узле W3C;

      IBM XSL Editor , www.alphaworks.ibm.com/tech/xsleditor. Редактор таблиц стилей XSLT на Java, обладающий визуальным интерфейсом для написания таблиц стилей и выражений выбора и совпадения. Однако необходимо, чтобы была установлена поддержка Java 2 version 1.1 (не 1.2 или 1.3);

      Stylus , www.exceloncorp.com/products/excelon_stylus.html. Stylus включает редактор таблиц стилей XSLT;

      Visual XML Transformation Tool , www.alphaworks.ibm.com/aw.nsf/techmain/visualxmltools. Visual XML Transformation Tool генерирует для вас XSLT для преобразования исходных документов в результирующие;

      Whitehill Composer , www.whitehill.com/products/prod4.html. WYSIWYG средство генерации таблиц стилей XSLT с поддержкой перетаскивания;

      XL-Styler , www.seeburger.de/xml. Включает выделение ключевых слов, завершение тегов, предварительный просмотр HTML и многое другое;

      XML Cooktop , http://xmleverywhere.com/cooktop/. Этот редактор только что выпущен и выглядит прилично. Включены средства разработки и проверки таблиц стилей XSLT;

      XML Spy , www.xmlspy.com/. При помощи этого редактора XML можно также редактировать XSLT;

      XML Style Wizard , www.infoteria.com/en/contents/download. Средство генерации файлов XSLT при помощи мастера, который изучает данные XML и задает вопросы пользователю;

      xslide , www.mulberrytech.com/xsl/xslide. Поддерживает режим редактирования XSLT для Emacs;

      XSpLit , www.percussion.com/xmlzone/technology.htm. Позволяет вам разделять документы HTML на определения DTD XML и таблицы стилей XSLT.

      Утилиты XSLT

      В Интернете существует также много утилит XSLT - в следующем списке перечислены наиболее известные:

      Microsoft XSL API Extension , http://msdn.microsoft.com/downloads/webtechnology/xml/xslisapi.asp. Упрощает задачу выполнения XSLT-преобразований на стороне сервера;

      Microsoft XSL-to-XSLT Converter , http://msdn.microsoft.com/downloads/webtechnology/xml/xsltconv.asp. Преобразует XSL в XSLT;

      XSL Lint , www.nwalsh.com/xsl/xslint. XSL Lint осуществляет проверку синтаксиса XSLT, позволяя обнаружить ошибки многих типов;

      XSL Trace , www.alphaworks.ibm.com/tech/xsltrace. Этот продукт позволяет пользователю проходить по шагам XSLT визуально;

      XSLT Compiler , www.sun.com/xml/developers/xsltc. Преобразует файлы XSLT в классы Java для преобразования файлов XML;

      XSLT test tool , www.netcrucible.com/xslt/xslt-tool.htm. Этот инструмент дает возможность запускать XSLT в различных популярных процессорах, что позволяет проверить, корректно ли ваше преобразование работает на всех системах. Существует возможность вызывать из командной строки MSXML3 от Microsoft, как и любой другой процессор XSLT;

      XSLTC , www3.cybercities.com/x/xsltc. Компилирует таблицы стилей XSLT в код на С++. Основан на Transformix, процессоре XSLT фирмы Mozilla;

      XSLTracer , www.zvon.org/xxl/XSLTracer/Output/introduction.html. XSLTracer - средство на языке Perl, демонстрирующее процесс обработки файлов XML при помощи таблиц стилей XSLT.

      На этом завершается обзор XSLT в данной главе. Как видите, нас ждет огромный набор сведений. В оставшейся части главы будет представлен обзор XSL-FO.

      Форматирующие объекты XSL: XSL-FO

      Самая популярная часть XSL - это XSLT-преобразования, с которыми мы уже познакомились в этой главе. Другая, существенно большая часть - это форматирующие объекты XSL, XSL-FO (XSL Formatting Objects).

      При помощи XSL-FO можно с точностью до миллиметра задать форматирование и способ отображения XML-документа. Для документов можно задать все, что угодно: шрифт текста, место, выравнивание, цвет, индексы, размер полей и многое другое. Работа с XSL-FO похожа на процесс создания вручную текстового процессора, и из-за сложности XSL-FO некоторые избегают их использовать. В главах 11 и 12 мы изучим то, что могут предложить нам XSL-FO, и способы работы с ними.

      Ресурсы XSL-FO

      Ряд ресурсов XSL-FO доступен в Интернете, но их гораздо меньше, чем ресурсов XSLT. Вот основные:

      Http://lists.w3.org/Archives/Public/www-xsl-fo/. Список заметок W3C для XSL-FO.

      Так же, как существуют процессоры XSLT, существуют и процессоры XSL-FO. Ни один из них, однако, не приближается к тому, чтобы реализовать стандарт полностью. Вот начальный список процессоров XSL-FO:

      FOP , http://xml.apache.org/fop. Приложение Java, которое считывает дерево форматирующих объектов XSL (создаваемое разборщиком XML) и создает документ PDF;

      PassiveTeX , http://users.ox.ac.uk/~rahtz/passivetex. Пакет ТеХ, форматирующий вывод XSL-FO в PDF. Использует разборщик XML xmltex Дэвида Карлайла (David Carlisle);

      SAXESS Wave , http://www.saxess.com/wave/index.html. Конвертер XML-Shockwave/Flash;

      TeXML , http://www.alphaworks.ibm.com/tech/texml. Преобразует документы XML в формат ТеХ;

      Unicorn Formatting Objects (UFO) , http://www.unicorn-enterprises.com. Процессор форматирующих объектов XSL, написанный на С++. Может генерировать вывод в форматах PostScript, PDF и других форматах, поддерживаемых драйверами DVI ТеХ;

      XEP , http://www.renderx.com/F02PDF.html. Процессор XSL-FO на Java, преобразующий форматирующие объекты XSL в PDF или PostScript.

      В этой книге я буду пользоваться FOP (formatting objects processor, процессор форматирующих объектов) - вероятно, самым распространенным процессором XSL-FO. Основанный на Java процессор XSL-FO берет XML-документ, написанный для использования форматирующих объектов XSL-FO, и преобразует его в формат PDF, который можно просмотреть в Adobe Acrobat. Хотя XSLT-преобразования часто производятся в HTML, для XSL-FO это работать не будет, потому что в этом случае указывается каждый аспект формата представления документа вплоть до мельчайших деталей, а для этих целей гораздо лучше подходит формат PDF.

      Форматирование документа XML

      Для форматирования

      в мы можем воспользоваться форматирующими объектами XSL-FO, представленными в главе 12. Например, вот как мы можем отобразить название первой планеты, Меркурия, при помощи форматирующих объектов XSL-FO и :

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

      На практике преобразования практически всегда выполняются при помощи таблиц стилей, и именно так мы поступим в главах 11 и 12. Все, что вам нужно сделать, это предоставить таблицу стилей XSLT, при помощи которой можно преобразовать ваш документ с использованием форматирующих объектов. При таком способе всю работу берет на себя процессор XSLT, преобразуя документ из представления, с которым вам удобно работать, в представление с форматирующими объектами, которое затем можно вставить в программу, способную обрабатывать форматирующие объекты и отображать форматированный результат.

      Чтобы пояснить все вышесказанное, ниже приведен пример работы с XML-документом, с которым мы уже встречались в этой главе,

      : .0553 58.65 1516 .983 43.4 .815 116.75 3716 .943 66.8 1 2107 1 128.4

      В этом примере я воспользуюсь таблицей стилей XSLT - мы посмотрим, как ее создавать, в главе 11 - для преобразования

      так, чтобы он использовал форматирующие объекты. Затем при помощи процессора FOP я преобразую новый документ в файл PDF. Мы также посмотрим, как форматированный документ выглядит в Adobe Acrobat. Таблица стилей XSLT

      В листинге 1.8 приведена таблица стилей

      , которая берет данные из и форматирует их в файл PDF, . В этом случае для текста я использую крупный шрифт - 36 пунктов. Листинг 1.8. Преобразование XML-XSL-FO xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fo="http://www.w3.org/1999/XSL/Format" version="1.0">
      margin-top="0mm" margin-bottom="10mm" margin-left="0mm" margin-right="0mm"/>
      font-weight="bold"
      font-size="36pt" line-height="48pt"
      font-size="36pt" line-height="48pt"
      font-size="36pt" line-height="48pt"
      font-size="36pt" line-height="48pt"
      font-size="36pt" line-height="48pt" Преобразование документа в представление с форматирующими объектами

      Для того чтобы преобразовать

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

      Например, чтобы создать

      при помощи Xalan, в Windows сначала нужно установить : C:\>set classpath=c:\xalan\xalan-1_2_0_0\bin\xalan.jar; c:\xalan\xalan-j_2_0_0\bin\xerces.jar

      Затем применить

      к для генерации : C:\planets>java org.apache.xalan.xslt.Process -IN planets.xml -XSL planetsPDF.xsl -OUT planets.fo

      Для задания форматирования документ

      использует форматирующие объекты XSL. Вот как выглядит файл (листинг 1.9): Листинг 1.9. planets.fo margin-right="20mm" margin-left="20mm" margin-bottom="10mm" margin-top="10mm" page-width="300mm" page-height="400mm" margin-right="0mm" margin-left="0mm" margin-bottom="10mm" margin-top="0mm"/> font-family="sans-serif" line-height="48pt" font-size="36pt" font-weight="bold"> font-family="sans-serif" line-height="48pt" font-family="sans-serif" line-height="48pt" font-family="sans-serif" line-height="48pt" font-family="sans-serif" line-height="48pt" font-family="sans-serif" line-height="48pt" Distance (million miles): 43.4 font-family="sans-serif" line-height="48pt" font-size="36pt" font-weight="bold"> font-family="sans-serif" line-height="48pt" font-family="sans-serif" line-height="48pt" font-family="sans-serif" line-height="48pt" font-family="sans-serif" line-height="48pt" font-family="sans-serif" line-height="48pt" Distance (million miles): 66.8 font-family="sans-serif" line-height="48pt" font-size="36pt" font-weight="bold"> font-family="sans-serif" line-height="48pt" font-family="sans-serif" line-height="48pt" font-family="sans-serif" line-height="48pt" font-family="sans-serif" line-height="48pt" font-family="sans-serif" line-height="48pt" Distance (million miles): 128.4

      Итак, мы успешно создали

      . Как нам теперь с его помощью создать форматированный файл PDF? Создание форматированного документа

      Чтобы обработать

      и создать форматированный (formatted) документ, я воспользуюсь процессором FOP Джеймса Таубера (James Tauber), который был подарен им проекту Apache XML Project.

      Главная страница процессора - http://xml.apache.org/fop; в настоящий момент FOP можно загрузить с http://xml.apache.org/fop/download.html. Пакет FOP, включая документацию, поставляется в формате zip, поэтому сначала его нужно распаковать FOP реализован как JAR-файл Java,

      , здесь я буду использовать FOP версии 0.15.

      FOP можно запустить из командной строки, используя класс Java, на момент написания книги называвшийся

      org.apache.fop.apps.CommandLine . Нужно предоставить разборщик XML - я буду использовать разборщик Xerces на Java в файле (он поставляется вместе с Xalan). Давайте рассмотрим, как в Windows, используя Java, при помощи FOP преобразовать в : в данном случае я указываю переменной ключом включить файл , а также два необходимых JAR-файла, входящих в состав загружаемого пакета FOP - и . (В этом примере предполагается, что все файлы , и расположены в каталоге ; если это не так, укажите полные пути к ним.) C:\planets>java -ср fop.jar:xerces.jar:w3c.jar org.apache.fop apps.CommandLine planets.fo planets.pdf

      Получившийся файл,

      , можно просмотреть в средстве чтения файлов PDF Adobe Acrobat Reader, как изображено на рис. 1.8. (Acrobat PDF Reader можно бесплатно загрузить с www.adobe.com/products/acrobat/readermain.html.) Документ изображен на рисунке отформатированным в соответствии с таблицей стилей .

      Рис. 1.8. Документ PDF, созданный при помощи форматирующих объектов


      Формат PDF - хороший формат для вывода форматирующих объектов, хотя он и обладает рядом ограничений - например, он не способен обрабатывать динамические таблицы, которые могут разворачиваться или сворачиваться по щелчку мыши, или интерактивные многоадресные ссылки (а ведь и те, и другие входят в спецификацию форматирующих объектов). Хотя в основных браузерах XSL-FO поддерживается довольно слабо, ожидается, что в будущем ситуация изменится, и браузеры будут поддерживать XSL-FO.

      Рассмотрим типичный пример рендеринга HTML.

      Дан список музыкальных композиций в виде XML-документа.

      Рихард Вагнер Полёт валькирии Эдвард Григ В пещере горного короля Иоган Бах Токката и фуга ре-минор Антонио Вивальди Времена года. Лето. Шторм Джузеппе Верди Триумфальный марш (Аида)

      Отобразим данный документ в виде HTML ul/li списка, как это показано ниже:

      Для этого используем следующее XSLT-преобразование:

    • Данное преобразование вернёт нам следующий HTML:

      • Рихард Вагнер - Полёт валькирии
      • Эдвард Григ - В пещере горного короля
      • ...

      XSLT-преобразование состоит из трёх шаблонов ( xsl:template). Каждый шаблон обслуживает свою сущность, что даёт нам возможность легко вносить изменения и делает код понятным.

      Если нам надо поменять отображение списка (например, добавить атрибут class), то мы редактируем шаблон match="PlayList" .

      Если же мы хотим изменить отображение элементов списка, то тут, совершенно очевидно, что стоить менять шаблон match="Track" .

      Фактически, XSLT не только даёт нам возможность разделить данные и представление (это задача любого шаблонизатора), но и позволяет разделять представления различных сущностей.

      Конечно, в более сложных случаях разделения добиться такого разделения бывает сложно. Очень легко прийти к ситуации, когда возникает «божественный шаблон», который делает всё, так же стоит бояться скатиться к «стрельбе дробью» кучей мелких шаблонов.

      Отладка XSLT

      Что мне очень нравится в XSLT, так это возможность отладки. Отладка помогает наглядно увидеть логику работы XSTL, структуру документа, значения переменных.

      Например, отладка поможет увидеть, что за сущность обрабатывает шаблон match="/" .

      В Visual Studio отладка XSLT запускается сочетанием клавиш ALT+F5 .

      Добавив в окно Watch XPath выражение " . " (точка), мы увидим, что текущий элемент шаблона - это корень (Root) документа. Здесь можно разместить контейнер div , или что-то относящееся ко всему XML-документу.

      Работа с сущностями XML

      Можно заметить, что в приведенных примерах присутствует сущность — Мы можем ее использовать, потому что определили ее в начале XSLT-документа

      Таким образом, — выводится, как символ с кодом — .

      Если нужно вывести строку «как есть», то стоит использовать CDATA следующим образом:

      Элемент xsl:text

      Хочу заострить внимание на элементе xsl:text . Он позволяет контролировать, что именно будет содержать TEXT-элемент. Значимость xsl:text очевидна на практике:

      XSLT-шаблон:

    • Полученный HTML:

    • Антонио Вивальди - Времена года. Лето. Шторм
    • Как видно из примера выше, отсутствие элемента xsl:text привело к появлению в HTML лишних переводов строк и пробелов.

      Безусловно, можно писать XSLT и без xsl:text , следующим образом:

    • Такой шаблон трудночитаем и есть большая вероятность, что при сопровождении в нём будут появлятся ошибки.

      Нужно стараться, чтобы форматирование XSLT-шаблона не влияло на результат трансформации. Именно поэтому я считаю, что использовать xsl:text - это хорошая практика.

      Ветвления

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

      Рассмотрим пример реализации ветвлений:

      Дополним предыдущий пример возможностью выводить сообщение «Список пуст» в случае, если PlayList не содержит элементов Track .

      Решение с использованием xsl:choose будет таким:

    • Решение с использованием дополнительного шаблона будет следующим:

    • Второе решение, на мой взгляд, выглядит красивее: новая функциональность не добавила нового кода в старые шаблоны, новый шаблон максимально изолирован.

      Если понадобится добавить картинку к сообщению о пустом списке, то в первом случае скорее всего разбухнет элемент xsl:when в шаблоне match="PlayList" . А вот во втором случае изменения будут только в специализированном шаблоне.

      В предыдущем примере мы разделили две абсолютно разные ветки рендеринга элемента списка. Но что если ветки различаются незначительно? Здесь использование xsl:if и xsl:choose вполне оправдано. Но мне бы хотелось показать другой подход: использование параметра mode у элемента xsl:template .

      В следующем примере навесим разные стили на чётные и нечётные элементы списка.

    • even odd

      Циклы и сортировка в XSLT

      Для циклов в XSLT есть элемент xsl:for-each , но схожий эффект можно получить, используя обычный xsl:apply-templates .

      Выведем список композиций, отсортированный по длительности.

      • Рихард Вагнер - Полёт валькирии - 280
      • Антонио Вивальди - Времена года. Лето. Шторм - 203
      • Иоган Бах - Токката и фуга ре-минор - 187
      • Эдвард Григ - В пещере горного короля - 163
      • Джузеппе Верди - Триумфальный марш (Аида) - 103

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

      Казалось бы, ничего страшного, но представим задачу, когда в списке встречаются композиции с Id и без. Для композиции с Id нужно отрендерить ссылку, а для остальных вывести только текст.

      Вариант с использованием xsl:for-each:

      Вариант с использованием xsl:apply-templates:

    • В случае xsl:for-each нам потребовалось добавлять ветвление, а в случае xsl:apply-templates - новый шаблон.

      Если бы шаблон match="PlayList" уже содержал ветвления и логику, то нам понадобилось некоторое время, чтобы разобраться, куда именно нам нужно вставить ветку. Вариант с xsl:apply-templates лишён этого недостатка, поскольку мы лишь декларируем новый шаблон, а не пытаемся внедриться в старые.

      Использование xsl:for-each имеет ещё одну большую опасность. Если вы видите произвольный участок кода внутри шаблона match="PlayList" , то предполагаете, что текущий элемент это PlayList , однако xsl:for-each меняет контекст. Увидев следующий код код:

      Вам потребуется внимательно присмотреться к контексту, чтобы понять, что select="." на самом деле выбирает текущий Track .

      Шаблон mode="TrackName" match="Track" был добавлен для избежания дублирования кода, отображаюшего название. Я не сделал этого раньше, потому что в этом не было необходимости. Как только я заметил дублирование, я провёл рефакторинг и вынес общую логику отображения в новый шаблон.

      xsl:for-each - это способ не плодить сущности. Вы просто добавляете логику отображения внутрь xsl:for-each и всё прекрасно работает. Проблемы начинаются потом, когда тело цикла разрастается, а проводить рефакторинг xsl:for-each намного сложнее, чем выносить дублированный код.

      Заключение

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

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

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

      Модель XML DOM. SAX: достоинства и недостатки. Спецификация XSL. XSLT и XPath. XSL-FO. XQuery.

      Для программной обработки XML документов используется модель XML DOM, которая определяет объекты и свойства всех XML элементов и методы (интерфейс) для доступа к ним. Иначе говоря, XML DOM описывает каким образом необходимо получать, изменять, добавлять и удалять XML элементы.

      Согласно DOM:

        все, что содержится внутри XML документа, является узлом;

        весь документ представляется узлом документа ;

        каждый XML элемент – узел элемента ;

        текст внутри XML элементов - текстовый узел ;

        каждый атрибут - узел атрибута ;

        комментарии - узлы комментариев .

      XML документ в соответствии с моделью XML DOM представляется как дерево из узлов, при этом:

        Все узлы дерева находятся в определенных отношениях друг с другом.

        Все узлы доступны через дерево. Их содержимое может быть изменено, удалено; новые элементы могут быть добавлены в дерево.

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

        Все узлы находятся в иерархических отношениях между собой.

        Эти отношения описываются с помощью понятий родитель, дочерний и потомок (все дочерние на одном уровне).

      Альтернативным интерфейсом для обработки XML документов является SAX .

      SAX (Simple API for XML ) - прикладной программный интерфейс для парсера с последовательным доступом к XML. Этот интерфейс предоставляет механизм чтения данных из XML документа.

      SAX парсер является поточным и управляемым событиями . Задачей пользователя SAX API заключается в описании методов, вызываемых событиями, возникающими при анализе документа.

      Такими событиями могут быть следующие:

        текстовый узел;

        узел элемента XML;

        инструкция обработки XML;

        комментарий XML.

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

      Анализ документа является однонаправленным (т.е. без возвратов по дереву).

      В отличие от DOM формальной спецификации для SAX не существует. В качестве нормативной рассматривается Java реализация SAX.

      Следует отметить следующие достоинства и недостатки SAX.

      Достоинства :

        Затраты памяти существенно меньше (зависит от максимальной глубины дерева документа и количества атрибутов в узле элемента), чем в случае DOM (требуется хранить в памяти все дерево документа).

        Скорость работы выше за счет сокращения затрат времени на выделение памяти для элементов дерева в случае DOM.

        Потоковое чтение данных с диска в случае DOM невозможно. Если для размещения всего документа в памяти недостаточно места, то использование SAX является безальтернативным.

      Недостатки :

        Процедура проверки правильности предполагает доступ ко всему документу одновременно.

        Это также требуется и в случае XSLT преобразования.

      Если загрузить "чистый" XML документ в веб-браузер, то можно будет увидеть древовидную структуру этого документа:

      В этом как раз и заключается главное отличие между XML и HTML, а именно разделение структуры документа и его представления в браузере. Конкретный вид XML документа описывается отдельно с помощью CSS или XSL.

      CSS и XSL - принципиально разные технологии, имеющие лишь частичное пресечение областей применения. CSS-форматирование применяется к HTML-документу браузером на клиентской стороне , а XSL-преобразование выполняется, как правило, на сервере , после чего результат отправляется браузеру клиента. XSL базируется на XML, благодаря чему XSL более гибок и универсален . У разработчиков имеется возможность использовать средства контроля за корректностью составления стилевых списков (используя схемы XML).

      С помощью XSL можно преобразовать XML-документ в формат HTML , WML , RTF , PDF , SQL , SWF , а так же в другой XML и XSL документ. XSL указывает как будет оформлен документ, где и каким образом должны размещаться данные.

      Cпецификация XSL состоит из трех частей:

        XSLT (XSL Transformations), язык для преобразования XML;

        XPath - язык путей и выражений, используемый в XSLT для доступа к отдельным частям XML-документа;

        XSL-FO (XSL Formatting Objects), язык для верстки XML.

      Наиболее распространенным механизмом XSLT преобразований для систем работающих на платформе Microsoft Windows является MSXML ; для систем на основе GNU - xsltproc .

      Для того, чтобы обработать XML документ c помощью XSL, необходимо в XML документе написать следующую инструкцию:

      < !-- ... -- >

      Возвращаясь к рассмотренному ранее примеру, добавив в XML файл ссылку на XSL файл, получим следующий код разметки:

      Проверка почтового ящика

      [email protected]

      [email protected]

      [email protected]

      Test

      Это письмо не является спамом

      [email protected]

      [email protected]

      Интересное предложение

      После загрузки данного документа в веб-браузере его вид кардинально изменится:

      Содержимое XSL файла mailbox.xsl приводится ниже:

      Почтовый ящик

      From: To:

      ,

      Subject:CCNotify



      XSLT и XPath

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

      Благодаря XSLT реализуется отделение данных от их представления в рамках парадигмы MVC (Model-view-controller ).

      XPath (XML Path Language) - язык запросов к элементам XML-документа. XPath был разработан для организации доступа к частям документа XML в файлах трансформации XSLT и является стандартом консорциума W3C. В языке XPath используется компактный синтаксис, отличный от принятого в XML. Начиная с версии 2.0, XPath является составной частью языка XQuery . XPath призван помочь обходить всевозможные деревья, получать необходимые элементы из другой ветви относительно точки обхода, распознавать предков, потомков, атрибуты элементов. Это полноценный язык навигации по дереву.

      Для нахождения элемента(ов) в дереве документа используются пути адресации.

      Каждый шаг адресации состоит из трех частей:

        оси, например child:: ;

        условия проверки узлов, например имена элементов документа body, html;

        предиката, например attribute::class .

      Дополнением к ядру языка является набор функций, которые делятся на 5 групп: системные функции, функции с множествами , строковые функции, логические функции, числовые функции.

      XSL-FO

      XSL-FO (eXtensible Markup Language Formatting Objects) - рекомендованный W3C язык разметки предпечатных материалов. По-сути, XSL-FO - это унифицированный язык представления. Он не имеет семантической разметки (как в HTML) и сохраняет все данные документа внутри себя (в отличие от CSS, который модифицирует представление по умолчанию для внешнего HTML или XML-документа) .

      В результате применения XSLT-преобразования к исходному XML документу получается его описание на языке XSL-FO . FO-процессор конвертирует XSL-FO-документ в какой-либо читаемый и/или печатаемый формат. Наиболее часто используется преобразование в PDF либо PS; некоторые FO-процессоры могут давать на выходе RTF-файлы либо просто показывать документ в окне.

      XQuery

      XQuery - язык запросов, разработанный для обработки данных в формате XML.

      В настoящее время рабочими группами консорциума W3C ведутся работы по развитию этого стандарта данного языка, с добавлением выражений для свободного поиска по тексту и для внесения изменений в XML документы и базы данных, а также для процедурных операций.

      В рамках стандарта SQL:2006 разработаны механизмы для встраивания XQuery -запросов непосредственно в SQL-запросы.