XSLT и другие языки
Несмотря на то, что XSLT является вполне самостоятельным языком, его очень часто используют как составную часть в проектах, которые пишутся на других языках программирования. Тому существует множество причин. Попытаемся выделить главные из них.
□ Традиционные императивные языки программирования очень плохо подходят для обработки древовидно структурированных данных. Программы, действия в которых непременно выполняются последовательно одно за другим, в общем случае не могут эффективно (с точки зрения компактности и понятности кода) обработать сложные иерархические структуры.
□ В некоторых случаях XSLT-преобразования документов оказываются, наоборот, настолько сложны, что из соображений эффективности и простоты бывает намного легче использовать традиционные языки.
□ Во многих проектах использование XSLT может обеспечить легкую и гибкую интеграцию. Например, если одним из этапов процедуры обмена XML-данными будет XSLT-преобразование, расширение количества форматов, известных системе, будет производиться не дописыванием исходного кода, а добавлением преобразований. А поскольку XSLT обеспечивает не только синтаксические, но и семантические преобразования, то есть преобразования на структурном уровне, роль этого языка в проектах интеграции, основанных на использовании XML, может быть очень велика.
□ Использование XSLT-преобразований может коренным образом упростить создание Web-ориентированных приложений. Надо сказать, что во многих случаях XSLT-преобразования просто избавляют от необходимости программировать что-либо на других языках; однако даже тогда, когда без традиционных подходов не обойдешься, XSLT служит хорошую службу, обеспечивая простой, удобный и легко настраиваемый вывод фрагментов HTML.
В этом разделе мы приведем примеры использования преобразований в различных языках и средах разработки. Конечно же, предлагаемые программы очень просты, но и их уже должно быть достаточно, чтобы начать применять XSLT в составе своих проектов.
Выполнение XSLT-преобразований в Object Pascal
В этой главе мы приведем пример использования XSLT-преобразований в простом проекте, созданном в среде разработки Delphi. Базовым языком Delphi является Object Pascal. Решение, которое мы предложим, будет основываться на использовании библиотеки MSXML Parser 3.0 от Microsoft.
Небольшое приложение, которое мы создадим, будет преобразовывать XML-документ (по умолчанию — "source.xml") при помощи XSLT-преобразования (по умолчанию — "stylesheet.xsl") и показывать результат преобразования.
Импорт MSXML в Delphi
Первым шагом после создания нового проекта (назовем его DelphiXML) будет импортирование библиотеки типов MSXML. Это позволит использовать в программе классы, интерфейсы и методы MSXML, в том числе и XSLT-процессор.
Для того чтобы импортировать библиотеку типов MSXML, выберем пункт меню Project/Import Type Library… (рис. 9.1).
Рис. 9.1. Импорт MSXML — шаг 1
В появившемся диалоге выберем пункт "Microsoft XML v3.0 (Version 3.0)" и создадим новый модуль кнопкой Create Unit (рис. 9.2).
Рис. 9.2. Импорт MSXML — шаг 2
Получившийся файл MSXML2_TLB.pas присоединим к проекту (Project/Add to Project…); теперь можно приступать к работе.
Для того чтобы использовать MSXML в нашем проекте, нам потребуется включить модуль MSXML2_TLB в список используемых модулей. Кроме того, для обработки исключений нам также потребуется модуль comobj. В итоге объявление uses будет выглядеть следующим образом:
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls,
Forms, Dialogs, StdCtrls, ComCtrls, MSXML2_TLB, comobj;
Форма проекта
Нам понадобится форма с тремя страничками и тремя компонентами TMemo. В первом будет показываться исходный текст преобразуемого документа, во втором — XSLT-преобразование и в третьем — результат преобразования.
Приблизительный внешний вид формы показан на рис. 9.3.
Рис. 9.3. Внешний вид формы проекта
Использование
DOMDocument
Объектная модель XML-документа в импортированной библиотеке будет представлена интерфейсом DOMDocument. В главном модуле проекта мы объявим две переменные, которые будут соответствовать обрабатываемому документу (xmlSource) и документу преобразования (xmlStylesheet):
var
xmlSource: DOMDocument;
xmlStylesheet: DOMDocument;
Для того чтобы создать экземпляры объектов наших документов, мы воспользуемся классом СoDOMDocument, который был создан в модуле MSXML2_TLB при импортировании. Метод Create этого класса создаст объекты, к методам и свойствам которых мы будем обращаться посредством уже упомянутого интерфейса DOMDocument:
xmlSource := CoDOMDocument.Create;
xmlStylesheet := CoDOMDocument.Create;
Для того чтобы загрузить XML-файл, мы воспользуемся функцией load интерфейса DOMDocument:
xmlSource.load('source.xml');
При загрузке файла вполне вероятны ошибки. Например, XML-документ может не являться хорошо оформленным. Для того чтобы успешно справиться с такого рода исключительными ситуациями, мы будем использовать конструкцию try...except и отрабатывать исключение EoleException:
try
xmlStylesheet.load('stylesheet.xsl');
memoStylesheet.Text := xmlStylesheet.xml;
except
on e: EOleException do
memoStylesheet.Text := e.Message;
end;
Для выполнения самого преобразования нам будет нужно использовать функцию transformNode:
try
memoResult.Text := xmlSource.transformNode(xmlStylesheet);
except
on e: EOleException do
memoResult.Text := e.Message;
end;
Для удобства мы можем также добавить диалоги для загрузки файлов и многое другое, но эти усовершенствования мы здесь разбирать не будем. Ограничимся тем, что приведем главную часть исходного кода этого проекта.
Листинг 9.1. Использование XSLT-преобразования в Delphi
unit source;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls, ComCtrls, MSXML2_TLB, comobj;
type
TMain = class(TForm)
{ Компоненты формы и обработчики событий }
private
public
end;
var
xmlSource: DOMDocument;
xmlStylesheet: DOMDocument;
Main: TMain;
implementation
{$R *.DFM}
procedure TMain.FormCreate(Sender: Tobject);
begin
xmlSource := CoDOMDocument.Create;
xmlStylesheet := CoDOMDocument.Create;
try
xmlSource.load('source.xml');
memoSource.Text := xmlSource.xml;
except
on e: EOleException do
memoSource.Text := e.Message;
end;
try
xmlStylesheet.load('stylesheet.xsl');
memoStylesheet.Text := xmlStylesheet.xml;
except
on e: EOleException do
memoStylesheet.Text := e.Message;
end;
end;
procedure TMain.pcMainChange(Sender: TObject);
begin
if pcMain.ActivePage = sheetResult then
try
memoResult.Text := xmlSource.transformNode(xmlStylesheet);
except
on e: EOleException do
memoResult.Text := e.Message;
end;
end;
{ Прочие процедуры и функции }
end.
Процесс использования нашего приложения приведен на следующих рисунках (рис. 9.4–9.6).
Рис. 9.4. Входящий документ
Рис. 9.5. Преобразование
Рис. 9.6. Выходящий документ
Выполнение XSLT-преобразований в C/C++
В качестве примера использования XSLT в языках С и С++ мы приведем очень простую программу, которая выполняет над документом source.xml преобразование stylesheet.xsl и выводит результат в файл document.out. На этот раз в качестве процессора мы будем использовать Xalan-C++, а в качестве среды разработки — Microsoft Visual С++.
Настройка путей
Для того чтобы использовать библиотеки Xalan в своем проекте, прежде всего, необходимо включить в исходный код файлы заголовков:
#include "util/PlatformUtils.hpp"
#include "XalanTransformer/XalanTransformer.hpp"
Файл PlatformUtils.hpp относится к библиотеке Xerces-C++, который используется в Xalan в качестве парсера XML-документов. Файл заголовка XalanTransformer.hpp относится к классу XalanTransformer, который мы и будем использовать для преобразования нашего документа.
Заголовочные файлы Xalan и Xerces могут быть найдены в поставке Xalan в каталогах xml-xalan\c\src и xml-xerces\c\src соответственно. Для того чтобы они могли быть обнаружены компилятором, эти пути следует явным образом прописать в настройках среды (меню Tools/Options), как показано на рис. 9.7.
Рис. 9.7. Настройка путей Xalan в MSVC
Для того чтобы скомпилированный объектный код мог быть скомпонован, в проекте также должны быть указаны пути к библиотечным файлам Xalan (рис. 9.8).
Рис. 9.8. Настройка путей библиотек в проекте
Использование класса
XalanTransformer
Теперь, когда мы разобрались со всякого рода настройками, можно заняться самой программой. Типичный сценарий использования Xalan в программе можно проиллюстрировать следующим кодом.
Листинг 9.2. Типовой сценарий использования Xalan
// Инициализируем Xerces
XMLPlatformUtils::Initialize();
// Инициализируем класс XalanTransformer
XalanTransformer::initialize();
// Создаем экземпляр класса XalanTransformer
XalanTransformer theXalanTransformer;
...
// Выполняем преобразование
theXalanTransformer.transform( ... );
...
// Освобождаем XalanTransformer
XalanTransformer::terminate();
// Освобождаем Xerces
XMLPlatformUtils::Terminate();
В соответствии с этим сценарием наша программа будет выглядеть следующим образом:
#include "StdAfx.h"
#include "util/PlatformUtils.hpp"
#include "XalanTransformer/XalanTransformer.hpp"
#include "strstream"
int main(int argc, const char* argv[]) {
using std::cerr;
// Инициализируем Xerces
XMLPlatformUtils::Initialize();
// Инициализируем класс XalanTransformer
XalanTransformer::initialize();
// Создаем экземпляр класса XalanTransformer
XalanTransformer theXalanTransformer;
// Выполняем преобразование
int theResult = theXalanTransformer.transform("source.xml",
"stylesheet.xsl", "document.out");
// В случае, если произошла ошибка, выводим, информацию о ней
if (theResult != 0) {
cerr << "XalanError: \n" << theXalanTransformer.getLastError();
}
// Освобождаем XalanTransformer
XalanTransformer::terminate();
// Освобождаем Xerces
XMLPlatformUtils::Terminate();
return theResult;
}
Выполнение XSLT-преобразований в PHP
Начиная с четвертых версий, PHP поставляется вместе с XSLT-процессором Sablotron, который включен в РНР в качестве расширения.
Для того чтобы использовать Sablotron в PHP-скриптах, следует выполнить следующие действия:
1. Убедиться, что файл php_sablot.dll присутствует в каталоге расширений.
2. Убедиться, что в файле php.ini присутствует строка extension=php_sablot.dll.
3. Убедиться, что библиотеки expat.dll и sablot.dll находятся в каталоге, указанном в переменной окружения PATH.
Замечание
Приведенное описание касается только использования Sablotron на платформе Windows32. На других платформах потребуется сконфигурировать РНР с флагом --with-sablot . В остальном установка совершенно аналогична.
Теперь, когда библиотека Sablotron подключена, мы сможем написать небольшую программу, которая будет выводить страницу гостевой книги.
Страница гостевой книги
Предположим, что мы храним (или экспортируем) данные гостевой книги в следующем формате.
Листинг 9.3. Данные гостевой книги — файл source.xml
Для того чтобы вывести форму гостевой книги и сообщения, содержащиеся в source.xml, мы создадим следующее преобразование.
Листинг 9.4. Преобразование stylesheet.xsl
version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
Краткие выводы
В заключение хотелось бы сделать несколько комментариев относительно применения XSLT и вообще XML-технологий.
Как и в любом другом случае, нужно очень тщательно взвешивать целесообразность применения в проекте тех или иных средств. К сожалению, шумиха вокруг XML имеет чисто коммерческий характер, маркетинговые службы часто выдают желаемое за действительное, объявляя XML серебряной пулей для всех проблем информационных технологий.
Как мы знаем, серебряных пуль не бывает. Нужно всегда очень трезво относиться к выбору технологий, хорошо понимая их плюсы, минусы и что каждый из этих знаков будет означать для конкретного проекта. Глупо вслепую следовать моде и тенденциям, не обращая внимания на возникающие при этом издержки.
С этих позиций XSLT является наименее проблемной технологией в том смысле, что если встает вопрос, использовать XSLT или нет, это уже означает: вопрос об использовании XML-технологий решен положительно. Значит, разработчики уже пошли на жертвы ресурсов памяти и процессорной мощности, которые XSLT вряд ли ужесточит. Иначе говоря, аппаратные требования не являются определяющими для использования XSLT.
Другое обстоятельство, которое необходимо принимать во внимание, — это сложность самого преобразования. Базовый набор элементов XSLT вкупе с расширениями уже представляется чрезвычайно мощным средством для выполнения различных преобразований, однако в некоторых случаях даже этого может быть недостаточно. В других случаях мощь XSLT может наоборот оказаться неоправданной — например, с задачей представления внешнего вида HTML-документа в Web-браузере могут великолепно справиться каскадные таблицы стилей (CSS).