Технология XSLT

Валиков Алексей Н.

Глава 2

Введение в XSLT

 

 

Документ = Данные + Структура

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

По большому счету, здесь XML заканчивается. Это не язык программирования, не язык операторов и функций, но язык структуры документа. Язык для простого и при этом очень четкого ее описания.

Важность роли, которую играет структура данных в программировании, сложно переоценить. В классической цитате Н. Вирта "Алгоритмы + Структуры данных = Программы", датированной 1976 годом, спустя четверть века "плюс" следует скорее трактовать, как знак умножения, но принцип остался верен: структура данных имеет ничуть не меньшее значение, чем алгоритм, который ее обрабатывает.

Успех XML можно, пожалуй, объяснить другим уравнением:

Документ = Данные + Структура

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

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

XSLT означает extensible Stylesheet Language for Transformations, что на русский язык традиционно переводится как "расширяемый язык стилей для преобразований". Название это скорее историческое, нежели смысловое — работа над XSLT была инициирована проектом XSL — extensible Stylesheet Language (расширяемым языком стилей).

Спецификация XSLT гласит, что это язык для преобразования одних XML-документов в другие XML-документы. Вне всякого сомнения, таковой и была изначальная идея XSLT. Очевидно, в процессе разработки язык перерос ее и теперь уместнее согласиться с редактором новой версии языка, Майклом Кеем (Michael Kay) в том, что XSLT — это язык для преобразования структуры документов.

 

XSLT как язык

 

По большому счету, любое преобразование можно условно поделить на три составляющие:

□ обращение к преобразуемому объекту;

□ создание результата преобразования;

□ логика, связывающая первые два действия и направляющая процесс преобразования.

Применительно к преобразованию XML-документов первая подзадача означает получение информации, которую этот документ содержит — в том числе и информации о структуре, которая является неотъемлемой его частью. Обращение в данном случае имеет несколько смыслов, в том числе — опрашивать, делать запросы, вычислять, выбирать; в общем смысле — задавать о документе вопросы и получать на них ответы. Для этой цели в XSLT служит язык, называемый XPath — язык путей в ХМL-документах (от англ. XML Path Language). Как мы увидим, XPath является лаконичным, но при этом чрезвычайно мощным средством обращения к XML-документам (а также к их частям). Роль XPath в XSLT так велика, что их можно было бы считать единым целым, если бы только XPath не использовался также и в других языках, предназначенных для работы с XML.

Вторая и третья условные части преобразования являются прерогативой самого XSLT. XSLT — это XML-язык в полном смысле этого слова: программы на XSLT (мы будем называть их преобразованиями сообразно их предназначению) являются хорошо оформленными (well-formed) XML-документами. XSLT также использует пространства имен; практически все имена, встречающиеся в XSLT, как-то: имена переменных, шаблонов, форматов и так далее — рассматриваются как расширенные имена, характеризуемые локальной частью вкупе с URI — уникальным идентификатором пространства имен.

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

В качестве первого примера XSLT-преобразования, который будет приведен в этой книге, мы рассмотрим классическую программу "Hello, world!". Листинг 2.1 показывает XSLT-интерпретацию "Hello, world!", когда мы преобразуем документ

Hello, world!

в документ вида:

Hello, world!

Листинг 2.1. Преобразование "Hello, world!"

 version="1.0"

 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

 

  

  

 

 

Исходный код, представленный выше, является хорошо оформленным XML-документом. Корневым его элементом является элемент xsl:stylesheet, который и обозначает преобразование. Атрибут version указывает на версию языка XSLT, в соответствии с которой был построен этот документ; помимо этого в элементе xsl:stylesheet объявляется пространство имен с префиксом xsl, которому соответствует URI "http://www.w3.org/1999/XSL/Transform". Все элементы преобразования, принадлежащие пространству имен с этим URI, будут восприняты процессором, как принадлежащие языку XSLT.

Элемент xsl:stylesheet имеет один-единственный дочерний элемент xsl:template, который и задает правило преобразования. Атрибут match указывает, что это правило должно обрабатывать элемент msg. Содержимое xsl:template является телом шаблона. Оно выполняется тогда, когда сам шаблон применяется к некоторой части документа. В данном случае тело шаблона будет выполнено, когда само правило будет применяться к элементу msg.

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

Содержимым элемента message является элемент xsl:value-of, который, в отличие от message принадлежит XSLT. Элемент xsl:value-of вычисляет XPath-выражение, заданное в его атрибуте select, и возвращает результат этого вычисления. XPath-выражение, ".", указанное в select, возвращает ту самую часть узла, которая обрабатывается в данный момент, иначе говоря — элемент msg.

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

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

Совсем иным является язык XPath, который представлен в нашем примере лаконичным выражением ".". XPath не придерживается XML-синтаксиса, напротив, он скорее похож на синтаксис путей в операционных системах — в главе 4 мы покажем, насколько верно это сравнение.

В приведенном преобразовании участвовала и третья синтаксическая конструкция, которая называется в XSLT паттерном (от англ. pattern — образец). Паттерн msg, заданный в атрибуте match элемента xsl:template указывает, какая именно часть XML-документа должна быть обработана этим правилом. Синтаксически паттерны являются XPath-выражениями (но не наоборот), однако смысл их различается. XPath-выражения вычисляются и возвращают результат, паттерны же просто устанавливают соответствие некоторому образцу. В нашем преобразовании паттерн msg указывает, что шаблон должен обрабатывать только элементы msg и никакие другие.

Каждое из шаблонных правил может вызывать другие шаблонные правила — в этом случае результат выполнения вызванных шаблонов включается в результат выполнения шаблона, который их вызывал. Для того чтобы продемонстрировать этот принцип мы немного перепишем шаблон "Hello, world!" с тем, чтобы он возвращал результат в виде HTML-документа.

Листинг 2.2. Преобразование "Hello, world!"' с результатом в HTML

 version="1.0"

 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

 

 

  

    Message

  

  

    

  

 

 

 

 

  

 

 

Результат применения этого преобразования к документу

Hello, world!

иллюстрирует листинг 2.3.

Листинг 2.3. Результат выполнения преобразования

 

  Message

 

 

  Hello, world!

 

В это преобразование мы добавили еще одно шаблонное правило:

 

 

   Message

 

 

  

 

 

Это правило определяет обработку корневого узла — в атрибуте match указан паттерн "/", что соответствует корню документа. Шаблон создает элементы html, head, title, body и в последний включает результат применения шаблонов к элементу msg. Сравнивая тело этого шаблона с результатом выполнения преобразования, можно заметить, что процессор скопировал все элементы, не принадлежащие XSLT, не изменяя их, а элемент xsl:apply-templates выполнил, применив шаблон к элементу msg и включив в body результат (он выделен в листинге полужирным шрифтом).

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

 

Отсутствие "побочных" эффектов

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

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

f(x, у) > вернуть x + у;

будет чистой функцией. Сколько бы раз мы ее не вызывали, ее результат все равно будет равен сумме аргументов. Кроме того, результат вычисления f(f(x1, y1), f(x2, y2)) будет равен x1 + y1 + x2 + y2, в каком бы порядке мы не вычисляли эти функции:

f(f(x1, y1), f(x2, y2)) = f(x1 + y1, f(x2, y2)) = x1 + y1 + f(x2, y2) = x1 + y1 + x2 + y2

f(f(x1, y1), f(x2, y2)) = f(f(x1, y1), x2 + y2) = f(x1, y1) + x2 + y2 = x1 + y1 + x2 + y2

f(f(x1, y1), f(x2, y2)) = f(x1, y1) + f(x2, y2) = x1 + y1 + f(x2, y2) = x1 + y1 + x2 + y2

и так далее.

Представим теперь похожую функцию, обладающую побочным эффектом:

f(x, у) → z присвоить x; увеличить z на у; вернуть z;

В данном случае побочный эффект состоит в изменении значения переменной z. В этом случае результат вычисления выражения f(z, f(x, у)) строго зависит от того, в каком порядке будут вычисляться функции — в одних случаях результатом будет x + у + z, в других 2∙x + 2∙у. Для того чтобы результат вычислений с побочными эффектами был детерминирован, требуется строгая определенность в порядке действий. В XSLT же эта строгая определенность отсутствует, преобразование — это набор правил, а не последовательность действий.

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

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

 

Расширения

Слово extensible (англ. расширяемый) в расшифровке аббревиатуры XSLT исторически происходит из названия языка XSL, но оно вполне применимо и к самому XSLT: спецификация этого языка позволяет разрабатывать собственные функции и элементы и использовать их в преобразованиях.

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

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

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

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

 

Преобразования снаружи

В общем случае в преобразовании участвуют три документа:

□ входящий документ, который подвергается преобразованию;

□ документ, который описывает само преобразование;

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

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

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

Рис. 2.1. Схема XSLT-преобразования

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

Рис. 2.2. Древовидные структуры в XSLT

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

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

□ К дереву входящего документа применяются правила, описанные в преобразовании. В итоге процессор создает дерево выходящего документа. Этот этап называется этапом преобразования.

□ Для созданного дерева генерируется физическая сущность. Этот этап называется этапом сериализации.

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

С сериализацией дела обстоят немного сложнее. С точки зрения преобразования, результирующее дерево — это все, что от него требуется, но вряд ли разработчику будет этого достаточно. Редко когда сгенерированная абстрактная древовидная структура — это то, что нужно. Гораздо чаще результат преобразования требуется получить в определенной физической форме.

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

Рис. 2.3. Сериализация в XSLT

Текущая версия языка поддерживает три основных метода сериализации: XML, HTML и текст. Каждый из этих методов учитывает синтаксис целевого физического формата и позволяет получить документ требуемого вида. Кроме того, имплементации XSLT могут добавлять собственные методы сериализации, генерируя документы в других форматах (например, PDF или TeX), не предусмотренных стандартными методами.

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

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

 

Области применения XSLT

 

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

Естественно, XSLT имеет также и некоторые ограничения:

□ XSLT не подходит для описания преобразований с очень сложной логикой;

□ XSLT не подходит для преобразований, которые требуют сложных вычислений.

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

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

Замечание

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

Ниже мы опишем наиболее классические области применения XSLT: Web-решения, использование в клиент-серверных приложениях и проекты интеграции.

 

XSLT в архитектуре клиент-сервер

 

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

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

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

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

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

Рис. 2.4. XML и XSLT в архитектуре клиент-сервер

 

XSLT на стороне сервера

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

Рис. 2.5. XSLT на стороне сервера

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

 

XSLT на стороне клиента

Идея использования XSLT на стороне клиента (рис. 2.6) заключается в том, чтобы отдавать клиенту отдельно нужные ему данные и отдельно преобразование, которое будет создавать для этих данных требуемое представление (например — HTML-страницу). Четкое разделение данных и их представления предоставит клиенту полную свободу распоряжаться полученной информацией. Преобразование в этом случае всего лишь предлагает возможную трактовку этой информации, ни к чему не обязывая.

Рис. 2.6. XSLT на стороне клиента

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

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

 

XSLT в Web-решениях

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

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

□ клиент запрашивает определенный документ;

□ сервер находит (или генерирует) этот документ;

□ сервер находит (или генерирует) преобразование, ассоциированное с этим документом, и применяет его к документу;

□ результат преобразования возвращается клиенту (например, в виде HTML-файла).

В подобной системе можно выделить три базовых компонента (рис. 2.7):

□ генератор — модуль, который создает документ на основе информации, хранящейся в базе данных или просто в файлах на сервере;

□ процессор преобразований — модуль, который применяет преобразования к сгенерированному документу;

□ сериализатор — модуль, создающий физическую репрезентацию результата преобразования.

Рис. 2.7. Декомпозиция системы Web-публикации

В таком виде XSLT создает сильную конкуренцию серверным скриптовым языкам типа ASP, JSP, PHP, Python и так далее. Web-системы, построенные на XML и XSLT, гораздо гибче и легче в реализации, а их масштабируемость нельзя даже сравнивать. В традиционных системах добавление еще одного представления данных (например, текстовой версии документа или версии "для печати") — это еще одна программа на сервере, в то время как в системах, использующих XSLT, — это всего лишь еще одно преобразование (рис. 2.8).

Рис. 2.8. Создание множественных представлений с использованием XSLT

XSLT является одной из основных технологий систем Web-публикации, как Cocoon от Apache XML Project и XSQL от Oracle. Решения на основе. Cocoon и XSQL отличаются мощностью, гибкостью и простотой; ожидается, что системы этого класса займут в скором времени лидирующие позиции.

 

XSLT при обмене данными

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

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

Действительно, предположим, что наши приложения уже имеют определенный XML-интерфейс (рис. 2.9):

Рис. 2.9. Приложение с XML-интерфейсом

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

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

Рис. 2.10. Интеграция приложения с XML-интерфейсом в общую схему

Упомянутая выше задача перевода, или, по-другому, преобразования, есть очевидная область применения языка XSLT. Общая схема интеграции на основе XML и XSLT показана на рис. 2.11.

Рис. 2.11. Схема интеграции приложений на основе XML/XSLT

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

 

История XSLT

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

 Предлагаем Вашему вниманию новый 3-x камерный

 Холодильник

 "Горск"

 объемом 250 л. и стоимостью всего 4500

 рублей!

 

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

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

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

Приведенные выше причины могут объяснить потребность в стандартной технологии для презентации XML-документов — технологии, подобной DSSSL (Document Style Semantics and Specification Language, язык семантики и спецификации стиля документа), которая существовала для SGML или CSS (Cascading Style Sheets — каскадные таблицы стилей) для HTML. Эта технология получила название XSL (extensible Stylesheet Language — расширяемый язык стилей), и именно ей обязан своим возникновением язык XSLT.

Первые идеи о создании отдельного языка для презентации документов были представлены на конференции WWW'94, где С.М. Шперберг-МакКвин и Роберт Гольдштейн выступили с докладом об использовании возможностей SGML во всемирной паутине. В этом докладе были сформулированы основные принципы языка стилей. Мы перечислим некоторые из них:

□ язык стилей должен быть декларативным (а не процедурным);

□ язык стилей должен уметь оперировать структурой документа;

□ презентация элемента может изменяться в зависимости от расположения этого элемента в документе;

□ реализация интерпретатора языка стилей не должна быть сложной даже в процедурном языке программирования;

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

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

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

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

После того, как требования к XSL были, наконец, сформулированы, разработка языка вылилась в создание целой серии черновых рабочих вариантов (в терминах W3C — working drafts, WD). Эти варианты зачастую сильно различались между собой, однако основные принципы XSL соблюдались в них неукоснительно.

С первых же рабочих версий XSL стало понятно, что задача презентации XML-документов состоит из двух главных подзадач: преобразование документа и описание внешнего вида результата этого преобразования. Разделение это было настолько четким, что спецификацию XSL более или менее независимо редактировали два человека: Джеймс Кларк (James Clark) и Стивен Дич (Stephen Deach). Кларк отвечал за преобразования (что в первых версиях называлось tree construction — конструирование дерева), Дич редактировал презентационную часть XSL (которую назвали formatting objects — форматирующие объекты).

Независимость и различия между двумя этими частями были настолько явными, что уже в третьей рабочей версии, которая вышла в свет 21 апреля 1999 года, технологию XSL разделили на два языка: XSL (расширяемый язык стилей) и XSLT (расширяемый язык стилей для преобразований). XSLT отвечал за преобразование входящего документа, XSL — за визуальное отображение результата этого преобразования. В дальнейшем эти два языка стали развиваться достаточно независимо (хотя они и были частями одной технологии).

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

Таким образом, технология XSL разделилась на три составные части: язык преобразований XSLT, язык обращений к XML-документам XPath и язык стилей XSL. На рис. 2.12 в графической форме показано развитие XSL с момента создания первой рабочей версии в августе 1998 года и до настоящего времени. Вершины графа соответствуют опубликованным версиям языков. WD означает working draft (рабочий черновой вариант), CR — candidate recommendation (кандидат в рекомендации), PR — proposed recommendation (предлагаемая рекомендация) и REC — рекомендация. Для тех, кто не знаком с деятельностью Консорциума W3 поясним, что любая технология, которой занимаются рабочие группы W3C, проходит ряд этапов: формирования требований, несколько рабочих версий, кандидат в рекомендации и предлагаемая рекомендация. Если все проходит успешно, технология становится технической рекомендацией Консорциума W3, что имеет статус стандарта де-факто (с тем лишь отличием, что стандарты могут принимать только организации, уполномоченные правительствами).

Рис. 2.12. История развития языка XSL в виде графа

Что касается XSLT и XPath, спецификации обоих этих языков стали техническими рекомендациями 16 ноября 1999 года. Сам же язык XSL, который теперь стали называть XSL-FO (аббревиатура FO означает formatting objects — форматирующие объекты), получил статус рекомендации не так быстро. Спустя год, в ноябре 2000, спецификация XSL получила статус кандидата в рекомендации, а еще через 9 месяцев с минимальными исправлениями — статус предлагаемой рекомендации. По всей видимости, к тому моменту, когда эта книга увидит свет, спецификация XSL уже будет официальной рекомендацией W3C.

Одного года было достаточно, чтобы XSLT стал широко использоваться во многих XSLT-задачах. Повышенное внимание разработчиков позволило выявить некоторые досадные огрехи, которые были допущены в первой версии XSLT, и потому в конце 2000 года была начата работа над версией 1.1. В новой версии рабочая группа XSL постаралась исправить большинство ошибок, допущенных в версии 1.0 и добавить некоторые возможности, которых не хватало в первой версии. Однако через некоторое время стало понятно, что разрабатываемый язык довольно сильно отличается от первой версии. К тому же, с учетом таких разработок, как XML Schema и XQuery возникла необходимость изменить модель данных и выражений XPath. В итоге, работу над версией 1.1 решено было прекратить и переключиться на создание вторых версий языков XSLT и XPath.

Вместо того чтобы разбирать в этой книге особенности версии 1.1, которая никогда не станет рекомендацией, в последней главе мы опишем то, что, согласно требованиям ко вторым версиям языков XSLT и XPath, ожидается в их спецификациях, и что, согласно XSLT 1.1 там точно будет. Работа над XSLT 2.0 и XPath 2.0 в самом разгаре: к сентябрю 2001 года были уже готовы три внутренних рабочих версии. К сожалению, открывать секреты рабочей группы XSL мы не в праве, хотя можно смело сказать, что процесс работы внушает оптимизм.