XSLT

Холзнер Стивен

Глава 10

Работа с API процессоров XSLT

 

 

Как вы видели на протяжении всей книги, при работе с XSLT вам не требовалось никакого программирования. Но все процессоры XSLT, с которыми мы работали до сих пор, — Xalan, Saxon, XT, Oracle и MSXML — разработаны так, что при желании к ним можно обращаться и из кода программы. Здесь мы рассмотрим, как работать с этими процессорами в прикладной программе. Можете спокойно пропустить эту главу, если вы не программист или не собираетесь им становиться. Но если вы не будете использовать возможности программного интерфейса, вы потеряете довольно много, в том числе поддержку XSLT на web-серверах. В этой главе будет также показано, как преобразовывать XML в реляционную базу данных.

Для взаимодействия с различными прикладными программными интерфейсами (API, Application Programming Interface) процессоров XSLT я буду применять Java и JavaScript. С различными процессорами XSLT можно работать и при помощи таких языков, как С++ или Visual Basic, но до сих пор подавляющее большинство программистов выбирало Java, а язык JavaScript удобен для обработки преобразований в Internet Explorer. Кроме того, используемые вами процессоры XSLT специально разработаны для взаимодействия с Java, хотя с процессором MSXML3 можно работать из программы как с СОМ-объектом. Как я говорил, с процессором MSXML в Internet Explorer можно работать при помощи JavaScript, такой пример был показан еще в главе 1. И, как я обещал в главе 1, здесь я рассмотрю его более подробно.

ПРОГРАММНОЕ ОБЕСПЕЧЕНИЕ ДЛЯ РАБОТЫ С XSLT ИЗМЕНЯЕТСЯ ОЧЕНЬ БЫСТРО!

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

 

XSLT и JavaScript в Internet Explorer

Любите вы Microsoft или нет, нельзя отрицать тот факт, что эта фирма включает в Internet Explorer все больше средств поддержки XSLT (дополнительную информацию можно найти по адресу http://msdn.microsoft.com/xml/general/xmlparser.asp), и поэтому работа с браузером заслуживает нашего внимания. В главе 1 я представил пример создания преобразований XSLT в Internet Explorer при помощи JavaScript, и здесь мы рассмотрим этот пример подробнее. Как вы помните (см. главу 2), IE версии 5.5 и младше может осуществлять настоящие преобразования XSLT, если они реализованы на JavaScript (новый, только что вышедший IE 6.0 может разбирать непосредственно синтаксис XSLT просто путем просмотра XML-документов).

В этом случае я, пользуясь MSXML и JavaScript, преобразую planets.xml при помощи planets.xsl. Для хранения этих документов я создаю два новых объекта, XMLDocument и XSLDocument, опираясь на классы ActiveXObject и DOMDocument процессора MSXML в функции xslt. (Эта функция запускается сразу при загрузке страницы, поскольку я установил атрибут onload элемента в «xslt()»). Я также создам объект, соответствующий элементу

, который отображает результаты преобразования:

 

  XSLT Using JavaScript

  

 

 

  

  

 

Эти результаты показаны на рис. 10.1.

Рис. 10.1. Использование JavaScript для преобразования документа

 

Обработка ошибок разбора

При использовании JavaScript для загрузки документов XML и XSL и работы с ними важно знать, как сообщать об ошибках разбора. В предыдущем примере я сообщал об ошибках, выводя сообщение «Error!» в элементе-приемнике

документа HTML, но это не очень информативно. Как получить дополнительную информацию? 

В следующем примере я намерено создаю ошибку разбора, изменив первый тег в planets.xml на тег :

 

  Mercury

  .0553

  58.65

  1516

  .983

  43.4

 

 .

 .

 .

Я установил свойство validateOnParse объекта XMLDocument в true (значение по умолчанию — false, что означает отсутствие проверки), поэтому процессор MSXML отловит эту ошибку разбора. Объект XMLDocument содержит объект parseError, и если его свойство errorCode не равно нулю, это означает наличие ошибки. Сейчас я хочу не просто вывести сообщение «Error!», а расшифровать ошибку при помощи новой функции getError, которая возвращает строку с информацией о месте и причине ошибки.

С целый получения этой дополнительной информации я использую свойства

Листинг 10.1. Создание преобразования XSLT и отображение ошибок разбора

 

  XSLT Using JavaScript

  

 

 

  

  

 

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

Рис. 10.2. Обработка ошибки разбора

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

 

Internet Explorer и динамические стили

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

Рис. 10.3. Поддержка динамических преобразований XSLT

Для сортировки таблицы я, как легко догадаться, применяю таблицу стилей с элементом (листинг 10.2). По умолчанию я сортирую планеты по названию.

Листинг 10.2. Применение динамических XSLT-преобразований

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

 

  

   

     </p> <p class="paragraph">      The Sorted Planets Table </p> <p class="paragraph">     

   

   

    

     The Sorted Planets Table

    

   

     

      

     

      

      

     

     

      

     

   

Name Mass Radius Day

  

 

 

 

  

  

   

   

   

  

 

Эта таблица стилей сортирует планеты в алфавитном порядке по их названиям; но есть и другие возможности: можно позволить пользователю осуществлять сортировку и по другому критерию. Для этого выберите в данной таблице стилей атрибут select элемента и при помощи JavaScript измените его динамически с «NAME» на «MASS», «RADIUS» или на другой критерий по желанию пользователя, и затем снова выполните преобразование XSLT. При повторном осуществлении преобразования появится новая таблица с новым порядком сортировки.

В качестве первого шага в создании нужной нам HTML-страницы я загружу planets.xml и требуемую таблицу стилей и выполню сортировку по умолчанию, то есть по названию планет:

 

  </p> <p class="paragraph">    Applying Dynamic Styles </p> <p class="paragraph">   

 

 .

 .

Теперь все, что осталось сделать, — снова выполнить преобразование и вывести результаты:

 

   </p> <p class="paragraph">    Applying Dynamic Styles </p> <p class="paragraph">   

 

 

 .

 .

 .

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

Листинг 10.3. Применение динамических XSLT-преобразований

 

   </p> <p class="paragraph">    Applying Dynamic Styles </p> <p class="paragraph">   

 

 

 

 

  

  

  

  

   

   

   

 

 

На самом деле загрузить документы XML и XSL в Internet Explorer можно несколькими способами. Для создания объектов XMLDocument и XSLDocument я использовал класс ActiveXObject, но эти объекты можно создавать и непосредственно обращаясь к содержащим документы XML объектам ActiveX по идентификатору класса, хранимому в реестре Windows. В следующем примере я таким образом загружу planets.xml и planets.xsl в XMLDocument и XSLDocument:

XMLDocument = document.all['XMLdoc'];

XSLDocument = document.all['XSLdoc'];

XMLDocument.load('planets.xml');

XSLDocument.load(' planets.xsl');

.

.

.

 CLASSID="clsid:f5078f32-c551-11d3-89b9-0000f81fe221">

 CLASSID="clsid:f5078f32-c551-11d3-89b9-0000f81fe221">

Эта техника не так надежна, как использование класса ActiveXObject, поскольку идентификаторы классов могут различаться в разных версиях Internet Explorer. (Приведены идентификаторы классов для Internet Explorer 5.5). Но есть еще один способ загрузить документы XML и XSL в Internet Explorer — при помощи участков (island) XML.

 

Internet Explorer и участки данных XML

В Internet Explorer есть специальный тег , при помощи которого можно создавать участки (island) XML. Участок XML может содержать либо сам код XML, либо ссылку на XML-документ.

Участки XML упрощают загрузку документов XML и XSL, поэтому их стоит здесь рассмотреть. В следующем примере я создаю два участка XML, sourceDocument и stylesheet, и загружаю planets.xml и planets.xsl, просто обратившись к ним через атрибут src:

 

   </p> <p class="paragraph">    The Planets Table </p> <p class="paragraph">   

 

  

  .

  .

  .

Теперь для осуществления XSLT-преобразования мне нужно только применить, как и раньше, метод transformNode и присвоить результаты элементу

, чтобы вывести их (листинг 10.4).

Листинг 10.4. Загрузка документов XML и XSL при помощи участков XML

 

   </p> <p class="paragraph">    The Planets Table </p> <p class="paragraph">   

 

  

 

 

 

 

  

  

 

Вот и все. Заметьте, что по умолчанию Internet Explorer 5.5 и младше использует устаревший процессор XSLT, как обсуждалось в главе 2 (если специально не установить процессор MSXML3 в режиме замены или IE 6.0, о чем также говорилось в главе 2). Если вы работаете с IE 5.5 или младше, у вас в распоряжении таблица стилей Internet Explorer прежнего образца, в которой нет правил по умолчанию и в которой вам придется использовать старое пространство имен XSL, как в этом примере (листинг 10 5).

Листинг 10.5. Таблица стилей Internet Explorer старого образца

 

  

   

     </p> <p class="paragraph">      The Planets Table </p> <p class="paragraph">     

   

   

    

     The Planets Table

    

   

     

     

      

      

      

     

    

   

Name Mass Radius Day

  

 

 

 

 

 

 

  

  

   

   

   

  

 

Как видите, при помощи JavaScript и XSLT в Internet Explorer можно сделать весьма многое. Дополнительную информацию можно подучить из руководства разработчика XSLT фирмы Microsoft, которое сейчас расположено по адресу http://msdn.microsoft.com/library/default.asp?URL=/library/psdk/xmlsdk/xslp8tlx.htm.

Пришло время рассмотреть взаимодействие XSLT с Java, начав с обращения к Java непосредственно из процессоров XSLT.

 

Вызов Java непосредственно из процессоров XSLT

Как мы говорили в главе 5, до недавнего времени процессоры XSLT могли реализовывать функции расширения любым способом, и один из этих способов включал прямой вызов функций Java. Например, в Saxon и Xalan можно выполнять код Java, если определить пространство имен, указывающее класс Java как последнюю часть своего URI — как в следующем примере, где я определил пространство имен Date, соответствующее классу Java Date:

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

 xmlns:Date="http://www.saxon.com/java/java.util.Date">

 .

 .

 .

Как вы видели в главе 5, это означает, что теперь вы можете применять такие функции Java, как toString и new, для встраивания текущей даты в заголовок HTML <Н1>, — например, так (листинг 10.6).

Листинг 10.6. Работа с функциями класса Date Java

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

 xmlns:Date="http://www.saxon.com/java/java.util.Date">

 

  

   

     </p> <p class="paragraph">      The Planets Table </p> <p class="paragraph">     

   

   

    

     The Planets Table

    

    

    

    

    

   

    

     

     

     

     

    

Name Mass Radius Day

   

  

 

 

  

   

   

   

   

  

 

 

 

 

 

  

 

 

 

 

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

Каждый из процессоров XSLT Xalan, Saxon, XT и Oracle определяет API, к которому можно обращаться из Java. Достаточно только проверить, что нужные файлы JAR находятся в classpath Java. Мы уже рассматривали, как работать с файлами JAR и путями к классам, в главе 1; теперь мы перейдем к написанию кода на Java, а не просто выполнению предопределенных классов из командной строки. Код можно загрузить с http://www.newriders.com/books/title.cfm?isbn=0735711364, поэтому если вы не программист на Java, можете пропустить эту часть главы.

 

Работа с API XSLT для Java

Во всех основанных на Java процессорах XSLT определен объемный интерфейс, API, для связи с Java. Как правило, при помощи API вызываются методы и создаются объекты Java, как мы увидим в этой главе. Но все процессоры XSLT определяют свои API по-разному, и обычно эти API довольно велики, поскольку каждый процессор может создавать собственные иерархии классов по своему усмотрению. В следующих разделах мы пройдем по этапам создания XSLT-преобразований из Java с использованием процессоров XSLT Xalan, Saxon, XT и Oracle. Все их возможности описаны в документации. Заметьте, что описание API большинства этих процессоров может само занять отдельную книгу, потому наше обсуждение вынужденно представляет собой лишь краткий обзор.

НАЗВАНИЯ ФАЙЛОВ JAVA

В отличие от остальных примеров книги, при создании файлов Java имеет значение имя файла. Java требует, чтобы имя файла совпадало с именем содержащегося в файле открытого класса. По этой причине для каждого листинга я включил в заголовок имя используемого файла. Например, заголовок «Листинг 10.7, xalanjava.java, взаимодействие Xalan с Java» означает, что перед тем, как использовать код листинга вместе с Java, необходимо сохранить листинг как xalanjava.java (для простоты имена всех открытых классов и файлов Java я писал в нижнем регистре). Обратите внимание: если вы загрузили код книги, этот пример будет называться 10-07.java, и перед работой с ним вам нужно будет его переименовать в xalanjava.java. Кроме того, требуемое имя файла будет приведено в комментариях в начале каждого файла Java.

 

Взаимодействие Xalan с Java

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

C:\>java xalanjava planets.xml planets.xsl planets.html

Чтобы создать XSLT-преобразование, я начну с создания объекта класса TransformerFactory в классе xalanjava:

import javax.xml.transform.Transformer;

import javax.xml.transform.TransformerFactory;

import javax.xml.transform.stream.StreamSource;

import javax.xml.transform.stream.StreamResult;

import javax.xml.transform.TransformerException;

import javax.xml.transform.TransformerConfigurationException;

import java.io.FileOutputStream;

import java.iо.FileNotFoundException;

import java.io.IOException;

public class xalanjava {

 public static void main(String[] args)

  throws TransformerException, TransformerConfigurationException,

  FileNotFoundException, IOException {

  TransformerFactory tFactory = TransformerFactory.newInstance();

  .

  .

  .

Имена документа XML, документа XSL и результирующего документа были нам переданы в аргументах соответственно как args[0], args[1]См. выпущенные издательством книги «XML и Java 2, библиотека программиста» и «XML, справочник». — Примеч. ред.
и args[2]. На следующем шаге нужно загрузить документ XSL в новый созданный мной объект TransformerFactory. Для этого я создал объект StreamSource и передал его в метод newTransformer объекта TransformerFactory, чтобы создать новый объект Transformer:

import javax.xml.transform.Transformer;

.

.

.

public class xalanjava {

 public static void main(String[] args)

  throws TransformerException, TransformerConfigurationException,

  FileNotFoundException, IOException {

  TransformerFactory tFactory = TransformerFactory.newInstance();

  Transformer transformer =

   tFactory.newTransformer(new StreamSource(args[1]См. выпущенные издательством книги «XML и Java 2, библиотека программиста» и «XML, справочник». — Примеч. ред.
));

  .

  .

  .

Объект transformer реализует XSLT-преобразование. Для того чтобы выполнить такое преобразование, нужно вызвать метод transform этого объекта, передав ему соответствующий XML-документу объект StreamSource и соответствующий результирующему документу объект StreamResult:

import javax.xml.transform.Transformer;

.

.

.

public class xalanjava {

 public static void main(String[] args)

  throws TransformerException, TransformerConfigurationException,

  FileNotFoundException, IOException {

  .

  .

  .

  transformer.transform(new StreamSource(args[0]),

   new StreamResult(new FileOutputStream(args[2])));

 }

}

Вот полный файл Java, xalanjava.java (листинг 10.7).

Листинг 10.7. xalanjava.java, взаимодействие Xalan с Java

import javax.xml.transform.Transformer;

import javax.xml.transform.TransformerFactory;

import javax.xml.transform.stream.StreamSource;

import javax.xml.transform.stream.StreamResult;

import javax.xml.transform.TransformerException;

import javax.xml.transform.TransformerConfigurationException;

import java.io.FileOutputStream;

import java.io.FileNotFoundException;

import java.io.IOException;

public class xalanjava {

 public static void main(String[] args)

  throws TransformerException, TransformerConfigurationException,

  FileNotFoundException, IOException {

  TransformerFactory tFactory = TransformerFactory.newInstance();

  Transformer transformer =

   tFactory.newTransformer(new StreamSource(args[1]См. выпущенные издательством книги «XML и Java 2, библиотека программиста» и «XML, справочник». — Примеч. ред.
));

  transformer transform(new StreamSource(args[0]),

   new StreamResult(new FileOutputStream(args[2])));

 }

}

Чтобы скомпилировать файл xalanjava.java в xalanjava.class и выполнить этот класс, задайте classpath так, чтобы путь включал Xalan и разборщик XML, который вы обычно используете с Xalan, Xerces (о Xerces говорилось в главе 1, в том числе и о том, где его взять), — в Windows это будет выглядеть так (как всегда, пишите пути в соответствии со своей системой):

C:\>set classpath=.;c:\xalan\xalan.jar;c:\xalan\xerces.jar

Затем скомпилируйте xalanjava.java компилятором с Java, javac:

C:\>javac xalanjava.java

Здесь считается, что путь к javac.exe прописан, и его можно сразу активизировать из командной строки. (Как правило, компилятор Java javac.exe находится в каталоге Java bin — поэтому если путь к нему не задан, к нему можно обратиться, например, так: C:\>c:\jdk1.3\bin\javac xalanjava.java.) Компилятор Java создаст файл xalanjava.class, при помощи которого производится преобразование:

C:\>java xalanjava planets.xml planets.xsl planets.html

При этом из файлов planets.xml и planets.xsl будет создан файл planets.html — здесь я его создал при помощи своего собственного класса Java.

РАБОТА С ПАКЕТОМ JAXP ФИРМЫ SUN ДЛЯ XSLT

Фирма Sun, создатель Java, обладает пакетом Java для обработки XML, JAXP, который можно загрузить с http://java.sun.com/xml. JAXP способен также осуществлять XSLT-преобразования. Но я не буду отдельно рассматривать JAXP в текущей главе, поскольку этот пакет (по крайней мере, сейчас) для всех своих преобразований использует Xalan, поставляемый в xalan.jar. Значит, предыдущий пример, листинг 10.7, без всяких изменений можно использовать с пакетом JAXP.

 

Взаимодействие Saxon с Java

Процессор Saxon также определяет API для работы с Java, но, конечно, в деталях этот прикладной интерфейс отличается от API Xalan. Для демонстрации создания преобразований при помощи Saxon API версии 6.0.2 я создам новый класс Java saxonjava. Начать нужно с создания нового объекта XSLTProcessor, вызвав метод newInstance класса Processor в файле saxonjava.java:

import java.io.*;

import org.xml.sax.*;

import org.w3c.dom.*;

import com.icl.saxon.trax.*:

public class saxonjava {

 public static void main(String args[])

  throws ProcessorException, ProcessorFactoryException,

  TransformException, SAXException, IOException {

  Processor processor = Processor.newInstance("xslt");

  .

  .

  .

Затем необходимо создать объект Templates на основе таблицы стилей XSL, которую мы хотим применить, хранимой в args[1]См. выпущенные издательством книги «XML и Java 2, библиотека программиста» и «XML, справочник». — Примеч. ред.
. Это можно сделать при помощи класса InputSource:

import java.io.*;

.

.

.

public class saxonjava {

 public static void main(String args[])

  throws ProcessorException, ProcessorFactoryException,

  TransformException, SAXException, IOException {

  Processor processor = Processor.newInstance("xslt");

  Templates templates =

   processor.process(new InputSource(args[1]См. выпущенные издательством книги «XML и Java 2, библиотека программиста» и «XML, справочник». — Примеч. ред.
));

  .

  .

  .

 }

}

При помощи нового объекта Templates можно создать объект Transformer, который в действительности делает работу:

import java.io.*;

.

.

.

public class saxonjava {

 public static void main(String args[])

  throws ProcessorException, ProcessorFactoryException,

  TransformException, SAXException, IOException {

  Processor processor = Processor.newInstance("xslt");

  Templates templates =

   processor.process(new InputSource(args[1]См. выпущенные издательством книги «XML и Java 2, библиотека программиста» и «XML, справочник». — Примеч. ред.
));

  Transformer transformer = templates.newTransformer();

  .

  .

  .

 }

}

Наконец, чтобы осуществить XSLT-преобразование, нужно вызвать метод transform объекта transformer, записывая результат в выходной документ при помощи объекта FileWriter (листинг 10.8).

Листинг 10.8. saxonjava.java, взаимодействие Saxon с Java

import java.io.*;

import org.xml.sax.*;

import org.w3c.dom.*;

import com.icl.saxon.trax.*;

public class saxonjava {

 public static void main(String args[])

  throws ProcessorException, ProcessorFactoryException,

  TransformException, SAXException, IOException {

  Processor processor = Processor.newInstance("xslt");

  Templates templates =

   processor.process(new InputSource(args[1]См. выпущенные издательством книги «XML и Java 2, библиотека программиста» и «XML, справочник». — Примеч. ред.
));

  Transformer transformer = templates.newTransformer();

  transformer.transform(new InputSource(args[0]),

   new Result(new FileWriter(args[2])));

 }

}

Чтобы скомпилировать и использовать новый класс saxonjava, нужно установить classpath так, чтобы переменная включала путь к saxon.jar:

С:\>set сlasspath=.;с:\saxon\saxon.jar

Затем при помощи компилятора Java, javac, создается saxonjava.class.

Как и многие использующие API процессоры XSLT, Saxon ожидает, что ему будут переданы URL документов, с которыми вы хотите работать, — что я и делаю на следующем шаге:

C:\>java saxonjava http://www.starpowder.com/planets.xml http://www.starpowder.com/planets.xsl planets.html

Таким образом, создается planets.html, как и раньше. Заметьте, что если документы расположены локально, можно использовать URL файла. Например, в Windows, если документ XML расположен в c:\XSL\saxonjava\planets.xml, а документ XSL в c:\XSL\saxonjava\planets.xsl, можно выполнить такую командную строку:

C:\>java saxonjava file:///XSL/saxonjava/planets.xml file:///XSL/saxonjava/planets.xsl planets.html

ПРЕОБРАЗОВАНИЕ ИМЕН ФАЙЛОВ В URL

Если вам больше нравится писать в командной строке имена файлов, а не URL, имена можно преобразовывать в URL в коде. Для этого необходимо передать полный путь к файлу в класс Java URL, а путь можно получить методом getAbsolutePath класса File: File file = new File(filename); String fullpath = file.getAbsolutePath();.

В этом примере мы работали с Saxon версии 6.0.2, о котором на web-узле Saxon говорится как о вполне надежной версии, но на момент написания книги появилась новая, полностью не протестированная версия Saxon 6.2.2. (Не существовало версии Saxon 6.1.x.) В последней версии Saxon, кажется, собирается вернуться к той же модели API, которую использует Xalan, и код, работоспособный в версии 6.0.2, не будет работать в версии 6.2.2 (сюрприз!). Ниже приведен код saxonjava.java для версии 6.2.2 — проверьте, что при работе с этим кодом вы включили в classpath новую версию saxon.jar, и обратите внимание на то, что при его выполнении вам нужно передавать не URL файлов, а только их имена. Этот код идентичен показанному ранее xalanjava.java, за исключением имени класса, saxonjava:

import javax.xml.transform.Transformer;

import javax.xml.transform.TransformerFactory;

import javax.xml.transform.stream.StreamSource;

import javax.xml.transform.stream.StreamResult;

import javax.xml.transform.TransformerException;

import javax.xml.transform.TransformerConfigurationException;

import java.io.FileOutputStream;

import java.io.FileNotFoundException;

import java.io.IOException;

public class saxonjava {

 public static void main(String[] args)

  throws TransformerException, TransformerConfigurationException,

  FileNotFoundException, IOException {

  TransformerFactory tFactory = TransformerFactory.newInstance();

  Transformer transformer =

   tFactory.newTransformer(new StreamSource(args[1]См. выпущенные издательством книги «XML и Java 2, библиотека программиста» и «XML, справочник». — Примеч. ред.
));

  transformer transform(new StreamSource(args[0]),

   new StreamResult(new FileOutputStream(args[2])));

 }

}

 

Взаимодействие процессора XSLT Oracle с Java

Несколько больше усилий потребуется для осуществления XSLT-преобразования при помощи API процессора XSLT фирмы Oracle. Новый пример, oraclejava.java, продемонстрирует работу с этим API.

В oraclejava.java в первую очередь необходимо считывать требуемые документы при помощи объекта DOMParser:

import org.w3c.dom.*;

import java.util.*;

import java.io.*;

import java.net.*;

import oracle.xml.parser.v2.*;

public class oraclejava {

 public static void main (String args[]) throws Exception {

  DOMParser parser;

  try {

   parser = new DOMParser();

   parser.setPreserveWhitespace(true);

   .

   .

   .

Затем, чтобы считать исходный документ XML и документ таблицы стилей XSLT, нужно преобразовать их URL в объекты URLJava при помощи метода parse объекта parser. После этого я вызываю метод разборщика getDocument, для того чтобы извлечь и сохранить документы XML и XSLT в объектах XMLDocument:

public class oraclejava {

 public static void main (String args[]) throws Exception {

  DOMParser parser;

  XMLDocument xmldoc, xsldoc;

  URL xslURL;

  URL xmlURL;

  try {

   parser = new DOMParser();

   parser.setPreserveWhitespace(true);

   xmlURL = new URL(args[0]);

   parser.parse(xmlURL);

   xmldoc = parser.getDocument();

   xslURL = new URL(args[1]См. выпущенные издательством книги «XML и Java 2, библиотека программиста» и «XML, справочник». — Примеч. ред.
);

   parser.parse(xslURL);

   xsldoc = parser.getDocument();

   .

   .

   .

В этот момент planets.xml и planets.xsl заключены в объекты XMLDocument. Для выполнения преобразования мне необходимы еще объекты XSLStylesheet и XSLProcessor для таблицы стилей XSLT. Фактическое преобразование XSLT осуществляется методом processXSL объекта parser, возвращающего фрагмент документа:

public class oraclejava {

 public static void main (String args[]) throws Exception {

  DOMParser parser;

  .

  .

  .

  xslURL = new URL(args[1]См. выпущенные издательством книги «XML и Java 2, библиотека программиста» и «XML, справочник». — Примеч. ред.
);

  parser.parse(xslURL);

  xsldoc = parser.getDocument();

  XSLStylesheet xslstylesheet = new XSLStylesheet(xsldoc, xslURL);

  XSLProcessor processor = new XSLProcessor();

  DocumentFragment docfragment =

   processor.processXSL(xslstylesheet, xmldoc);

  .

  .

  .

Этот код завершает преобразование. Теперь задача состоит в том, чтобы преобразовать данный фрагмент документа в документ XML, который можно записать на диск, — для чего я и создам новый XML-документ, newdoc, и вставлю фрагмент документа в корень нового документа:

import org.w3c.dom.*;

.

.

.

public class oraclejava {

 public static void main (String args[]) throws Exception {

  DOMParser parser;

  XMLDocument xmldoc, xsldoc, newdoc;

  URL xslURL;

  URL xmlURL;

  try {

   .

   .

   .

   DocumentFragment docfragment =

    processor processXSL(xslstylesheet, xmldoc);

   newdoc = new XMLDocument();

   Element rootElement = newdoc.createElement("root");

   newdoc.appendChild(rootElement);

   rootElement.appendChild(docfragment);

   .

   .

   .

Теперь осталось только сохранить на диске новый XML-документ с именем, заданным в args[2]. В этих целях я использую объект FileOutputStream, и вот полный код (листинг 10.9). 

Листинг 10.9. oraclejava.java, взаимодействие процессора XSLT Oracle с Java

import org.w3c.dom.*;

import java.util.*;

import java.io.*;

import java.net.*;

import oracle.xml.parser.v2.*;

public class oraclejava {

 public static void main (String args[]) throws Exception {

  DOMParser parser;

  XMLDocument xmldoc, xsldoc, newdoc;

  URL xslURL;

  URL xmlURL;

  try {

   parser = new DOMParser();

   parser.setPreserveWhitespace(true);

   xmlURL = new URL(args[0]);

   parser.parse(xmlURL);

   xmldoc = parser.getDocument();

   xslURL = new URL(args[1]См. выпущенные издательством книги «XML и Java 2, библиотека программиста» и «XML, справочник». — Примеч. ред.
);

   parser.parse(xslURL);

   xsldoc = parser.getDocument();

   XSLStylesheet xslstylesheet = new XSLStylesheet(xsldoc, xslURL);

   XSLProcessor processor = new XSLProcessor();

   DocumentFragment docfragment =

    processor.processXSL(xslstylesheet, xmldoc);

   newdoc = new XMLDocument();

   Element rootElement = newdoc.сreateElement("root");

   newdoc.appendChild(rootElement);

   rootElement.appendChild(docfragment);

   OutputStream out = new FileOutputStream(args[2]);

   newdoc.print(out);

   out.close();

  } catch (Exception e) {}

 }

}

На этом oraclejava.java заканчивается. Чтобы скомпилировать пример, включите в classpath путь к разборщику XML процессора XSLT Oracle, xmlparserv2.jar:

C:\>set classpath=.;c:\oraclexml\lib\xmlparserv2.jar

Затем скомпилируйте oraclejava.java, как мы это уже делали, компилятором Java javac. Для выполнения XSLT-преобразований нужно указать URL документов, с которыми вы хотите работать (если документы локальны, можно указать URL файлов, как и раньше):

C:\>java oraclejava http://starpowder.com/planets.xml http://starpowder.com/planets.xsl planets.html

 

Взаимодействие XT с Java

Процессор XT также может работать с Java. API XT спроектирован для работы с классами, определенными в Project X TR2 фирмы Sun, которые поддерживают обработку XML. Вам будет необходим файл xml.jar фирмы Sun, который можно получить, загрузив Project X TR2. Чтобы получить xml.jar, необходимо зарегистрироваться на web-узле разработчиков Sun, http://developer.java.sun.com, что, к счастью, бесплатно, хотя и потребует от вас заполнения изрядного количества форм.

Файл xml.jar нужен для класса com.sun.xml.tree.XmlDocument. Этот класс поддерживает XML-документы, и я начну свой новый пример, xtjava.java, с создания нового объекта XmlDocument для исходного документа, таблицы стилей XSLT и результирующего документа:

import java.io.IOException;

import java.io.OutputStream;

import java.io.FileOutputStream;

import org.xml.sax.SAXException;

import com.sun.xml.tree.XmlDocument;

import com.jclark.xsl.dom.Transform;

import com.jclark.xsl.dom.TransformEngine;

import com.jclark.xsl.dom.TransformException;

import com.jclark.xsl.dom.XSLTransformEngine;

class xtjava {

 public static void main(String[] args)

  throws IOException. SAXException, TransformException {

  XmlDocument XMLdoc =

   new XmlDocument().createXmlDocument(args[0]);

  XmlDocument XSLdoc =

   new XmlDocument().createXmlDocument(args[1]См. выпущенные издательством книги «XML и Java 2, библиотека программиста» и «XML, справочник». — Примеч. ред.
);

  XmlDocument newdoc = new XmlDocument();

  .

  .

  .

После этого я создаю объект XSLTranformationEngine и вызываю его метод createTransform для создания нового объекта Transform на основе таблицы стилей XSLT:

import java.io.IOException;

.

.

.

class xtjava {

 public static void main(String[] args)

  throws IOException, SAXException, TransformException {

  XmlDocument doc = new XmlDocument();

  XSLTransformEngine transformEngine = new XSLTransformEngine();

  Transform transform = transformEngine.createTransform(XSLdoc);

  .

  .

  .

Затем я могу преобразовать XML-документ в объект результирующего документа следующим способом:

import java.io.IOException;

.

.

.

class xtjava {

 public static void main(String[] args)

  throws IOException, SAXException, TransformException {

  XmlDocument XMLdoc =

   new XmlDocument().createXmlDocument(args[0]);

  XmlDocument XSLdoc =

   new XmlDocument().createXmlDocument(args[1]См. выпущенные издательством книги «XML и Java 2, библиотека программиста» и «XML, справочник». — Примеч. ред.
);

  XmlDocument newdoc = new XmlDocument();

  XSLTransformEngine transformEngine = new XSLTransformEngine();

  Transform transform = transformEngine.createTransform(XSLdoc);

  transform transform(XMLdoc, newdoc);

  .

  .

  .

Так завершается преобразование. Осталось только записать результирующий документ, newdoc, на диск, что можно сделать при помощи объекта FileOutputStream (листинг 10.10).

Листинг 10.10. xtjava.java, взаимодействие XT с Java

import java.io.IOException;

import java.io.OutputStream;

import java.io.FileOutputStream;

import org.xml.sax.SAXException;

import com.sun.xml.tree.XmlDocument;

import com.jclark.xsl.dom.Transform;

import com.jclark.xsl.dom.Transform Engine;

import com.jclark.xsl.dom.TransformException;

import com.jclark.xsl.dom.XSLTransformEngine;

class xtjava {

 public static void main(String[] args)

  throws IOException, SAXException, TransformException {

  XmlDocument XMLdoc =

   new XmlDocument().createXmlDocument(args[0]);

  XmlDocument XSLdoc =

   new XmlDocument().createXmlDocument(args[1]См. выпущенные издательством книги «XML и Java 2, библиотека программиста» и «XML, справочник». — Примеч. ред.
);

  XmlDocument newdoc = new XmlDocument();

  XSLTransformEngine transformEngine = new XSLTransformEngine();

  Transform transform = transformEngine.createTransform(XSLdoc);

  transform.transform(XMLdoc, newdoc);

  OutputStream out = new FileOutputStream(args[2]);

  newdoc.write(out);

  out.close();

 }

}

Чтобы запустить пример, включите xt.jar и xml.jar в classpath:

C:\>set classpath=.;d:\xt\xt.jar;xml.jar

Скомпилируйте теперь xtjava.java компилятором Java javac и запустите на выполнение следующим образом, передав URL документов XML и XSL (можно передать и URL файлов, как было показано ранее):

C:\>java xtjava http://www.starpowder.com/planets.xml http://www.starpowder.com/planets.xsl planets.html

Теперь все сделано.

 

Преобразование XML в реляционную базу данных

При обсуждении дополнительных возможностей XSLT стоит упомянуть элементы расширения SQL процессора Saxon. Через драйвер Java Database Connectivity (JDBC) можно работать с реляционными базами данных. Мы уже рассмотрели преобразования из XML в XML, в простой текст, в RTF, в JavaScript и т.д. Теперь пришла очередь преобразованию XML в реляционную базу данных.

РАБОТА С ИНТЕРПРЕТИРУЕМЫМ SAXON

Обратите внимание: для связи с базами данных через JDBC нельзя использовать исполняемый файл для Windows saxon.exe. Нужно запустить реализующий Saxon класс Java com.id.saxon.StyleSheet, как я сделаю в конце примера. 

В примере я передам данные planets.xml в базу данных формата Microsoft Access planets.mdb. Если вы хотите повторить пример, создайте этот файл базы данных, в нем — таблицу planets с четырьмя текстовыми полями Name, Mass, Radius и Day, а оставшуюся часть файла оставьте пустой. В Windows я зарегистрирую этот файл базы данных в качестве источника ODBC с именем «planets» через значок Data Sources (ODBC) (Источники данных (ODBC)) в панели управления (в Windows 2000 он расположен в панели управления в папке Administrative Tools (Администрирование)). При запуске пример считает данные планет из planets.xml и добавит их в файл базы данных, planets.mdb.

Для подключения к этой базе данных через JDBC я применил элемент процессора Saxon. Префикс пространства имен sql определяется в Saxon следующим образом:

 xmlns:sql="http://icl.com/saxon/extensions/com.icl.saxon.sql.SQLElementFactory"

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

 .

 .

 .

Для фактического подключения к источнику данных planets служит элемент расширения с атрибутами database, user, password и driver. Для работы через JDBC установите атрибут driver в «sun.jdbc.odbc.JdbcOdbcDriver», атрибут database — в источник данных ODBC, «jdbc:odbc:planets», а атрибуты user и password — в имя пользователя и пароль, нужные для подключения к базе данных. Здесь нам не требуется задавать имя пользователя и пароль, но я задал этим параметрам шаблонные значения, так как они требуются в большинстве приложений баз данных:

 xmlns:sql="http://icl.com/saxon/extensions/com.icl.saxon.sql.SQLElementFactory"

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

 

 

 

 

 

   password="{$password}" driver="sun.jdbc.odbc.JdbcOdbcDriver"

   xsl:extension-element-prefixes="sql"/>

 

 

 .

 .

 .

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

 xmlns:sql="http://icl.com/saxon/extensions/com.icl.saxon.sql.SQLElementFactory"

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

 .

 .

 .

 

 

   password="{$password}" driver="sun.jdbc.odbc.JdbcOdbcDriver"

   xsl:extension-element-prefixes="sql"/>

 

 

 

 

   .

   .

   .

 

 

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

 xmlns:sql="http://icl.com/saxon/extensions/com.icl.saxon.sql.SQLElementFactory"

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

 .

 .

 .

 

 

   

   

   

   

  

 

В идеале этого должно быть достаточно, но при работе с самым последним драйвером Access в конце операции Saxon не сбрасывает все буфера данных. Это значит, что данные о последней планете в planets.xml, Земле, не будут отправлены в базу данных. Чтобы сбросить буферы данных, я явно вызываю шаблон как именованный шаблон, применяя с данными-заглушкой (листинг 10.11).

Листинг 10.11. Работа с реляционной базой данных

 xmlns:sql="http://icl.com/saxon/extensions/com.icl.saxon.sql.SQLElementFactory"

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

 

 

 

 

 

   password="{$password}" driver="sun.jdbc.odbc.JdbcOdbcDriver"

   xsl:extension-element-prefixes="sql"/>

 

 

 

 

  

  

   

     xsl:extension-element-prefixes="sql">

     

    

    

    

   

   

   

  

    xsl:extension-element-prefixes="sql">

    

    

    

    

   

  

 

Эта таблица стилей правильно добавляет три записи в базу данных planets.mdb: по одной новой записи для каждой из планет. Как я говорил, здесь нельзя использовать готовый исполняемый файл saxon.exe, нужно применять класс Java com.icl.saxon.StyleSheet. Сначала нужно включить в classpath файл saxon.jar:

C:\>set classpath=.;c:\saxon\saxon.jar

После этого я могу передать в класс com.icl.saxon.StyleSheet файл planets.xml и таблицу стилей из листинга 10.11:

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

Теперь все сделано — данные планет вставлены в planets.mdb. Результаты применения этой таблицы стилей показаны на рис. 10.4, где я открыл planets.mdb в Microsoft Access. Таким образом, мы рассмотрели преобразование из XML в реляционную базу данных.

Рис. 10.4. Применение расширений SQL Saxon

Еще один аспект XSLT, в котором вам потребуется программирование, это поддержка XSLT на серверах. В качестве демонстрации далее я преобразую planets.xml при помощи planets.xsl с использованием активных серверных страниц (Active Server Pages, ASP) фирмы Microsoft, серверных страниц Java (Java Server Pages, JSP) фирмы Sun и сервлетов (servlet) Java, выполняющихся на web-серверах и возвращающих результирующий документ браузеру пользователя.

За недостатком места мы не можем подробно рассмотреть эти технологии, и если вы с ними не знакомы, вы можете получить дополнительную информацию в Интернете (как всегда, URL могут измениться):

• ASP. http://msdn.microsoft.com/workshop/c-frame.htm#/workshop/server/Default.asp (руководство и документация по ASP фирмы Microsoft);

• JSP. http://java.sun.com/products/jsp/ (главная страница Sun, посвященная JSP);

• Сервлеты. http://java.sun.com/products/servlet/ (главная страница Sun, посвященная сервлетам).

 

Применение XSLT с активными серверными страницами

Активные серверные страницы (Active Server Pages, ASP) выполняются на серверах Microsoft Windows NT или 2000, поэтому в ближайшем примере для преобразования planets.xml при помощи planets.xsl и возврата результата в виде документа HTML я воспользуюсь процессором Microsoft MSXML.

Это все то же преобразование, которое нам уже много раз встречалось, — создание HTML-таблицы данных о планетах — но на этот раз преобразование будет выполнено на web-сервере, который затем отправит его пользователю. В начале сценария ASP я установил тип содержимого MIME результирующего документа в «text/html», поэтому он будет трактоваться как HTML:

<%@LANGUAGE="VBScript"%>

<%

 Response.ContentType = "text/html"

 .

 .

 .

Затем, во многом аналогично предыдущим примерам в этой главе с JavaScript, я создаю два объекта документа MSXML, один для документа XML, а другой — для документа XSL:

<%@LANGUAGE="VBScript"%>

<%

 Response.ContentType = "text/html"

 Dim docXML

 Dim docXSL

 Set docXML = Server.CreateObject("MSXML2.DOMDocument.3.0")

 Set docXSL = Server.CreateObject("MSXML2.DOMDocument.3.0")

 .

 .

 .

Процедура загрузки этих документов на сервере во многом похожа на процедуру с использованием JavaScript, за тем исключением, что здесь правильные пути файлов получаются при помощи метода MapPath объекта Server. В данном случае я поместил planets.xml и planets.xsl в тот же каталог, что и сценарий ASP, поэтому документы загружаются так:

<%@LANGUAGE="VBScript"%>

<%

 Response.ContentType = "text/html"

 Dim docXML

 Dim docXSL

 Set docXML = Server.CreateObject("MSXML2.DOMDocument.3.0")

 Set docXSL = Server.CreateObject("MSXML2.DOMDocument.3.0")

 docXML.ValidateOnParse = True

 docXSL.ValidateOnParse = True

 docXML.load Server.MapPath("planets.xml")

 docXSL.load Server.MapPath("planets.xsl")

 .

 .

 .

Теперь нам осталось только применить метод transformNode (как в примере с JavaScript раньше) для выполнения XSLT-преобразования и вывода результатов (листинг 10.12). 

Листинг 10.12. XSLT на сервере с применением ASP

<%@LANGUAGE="VBScript"%>

<%

 Response.ContentType = "text/html"

 Dim docXML

 Dim docXSL

 Set docXML = Server.CreateObject("MSXML2.DOMDocument.3.0")

 Set docXSL = Server.CreateObject("MSXML2.DOMDocument.3.0")

 docXML.ValidateOnParse = True

 docXSL.ValidateOnParse = True

 docXML.load Server.MapPath("planets.xml")

 docXSL.load Server.MapPath("planets.xsl")

 strOutput = docXML.transformNode(docXSL)

 Response.Write strOutput

%>

Результат этого преобразовании ASP показан на рис. 10.5. Теперь вы научились выполнению XSLT-преобразований на web-серверах.

Рис. 10.5. Применение XSLT с ASP

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

<%@LANGUAGE="VBScript"%>

<%

 Response ContentType = "text/html"

 If instr(request,servervariables("http_user_agent"), "MSIE") = 0 then

  Response.Write "Sorry, not optimized for your device."

  Response.End

 End If

 .

 .

 .

ОТДЕЛЕНИЕ ДАННЫХ ОТ ИХ ПРЕДСТАВЛЕНИЯ

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

 

Применение XSLT с Java Server Pages

Для работы с активными серверными страницами я использовал процессор MSXML фирмы Microsoft, но серверные страницы Java (Java Server Pages, JSP) не обязаны выполняться на серверах на платформе Windows, поэтому с JSP я не использую MSXML. Для выполнения XSLT-преобразования и отправки результатов в браузер клиента я воспользуюсь API процессора Xalan для работы с Java.

Например, при помощи Xalan можно создать planets.html на сервере как временный документ (этот код предполагает, что planets.xml и planets.xsl расположены в том же каталоге, что и сценарий JSP) таким образом:

<%@ page errorPage="error.jsp" language="java"

 contentType="text/html" import="org.apache.xalan.xslt.*;java.iо.*" %>

<%

 try {

  XSLTProcessor processor = XSLTProcessorFactory.getProcessor();

  processor.process(new XSLTInputSource("planets.xml"),

   new XSLTInputSource("planets.xsl"),

   new XSLTResultTarget("planets.html"));

 } catch(Exception e) {}

 .

 .

 .

Теперь все, что нужно сделать, — это открыть документ и отправить его обратно клиенту (листинг 10.13).

Листинг 10.13. XSLT на сервере с применением JSP

<%@ page errorPage="error.jsp" language="java"

 contentType="text/html" import="org.apache.xalan.xslt.*;java.iо.*" %>

<%

 try {

  XSLTProcessor processor = XSLTProcessorFactory.getProcessor();

  processor.process(new XSLTInputSource("planets.xml"),

   new XSLTInputSource("planets.xsl"),

   new XSLTResultTarget("planets.html"));

 } catch(Exception e) {}

 FileReader filereader = new FileReader("planets.html");

 BufferedReader bufferedreader = new BufferedReader(filereader);

 String instring;

 while((instring = bufferedreader.readLine()) != null) { %>

  <%= instring %>

 <% } 

 filereader.close();

 pw.close();

%>

Теперь все готово. Результаты применения этого сценария JSP показаны на рис. 10.6.

Рис. 10.6. Применение XSLT с JSP

 

Применение XSLT с сервлетами Java

Выполнять XSLT-преобразования на сервере можно также при помощи сервлетов (servlet) Java. Хотя многие процессоры XSLT предоставляют свои собственные версии сервлетов, я считаю, что гораздо проще самостоятельно выполнить преобразование при помощи Xalan или другого процессора XSLT и затем обработать результирующий документ и отправить его обратно клиенту.

В следующем примере я при помощи Xalan преобразую planets.xml во временный файл planets.html, применяя planets.xsl в сервлете:

import java.net.*;

import java.sql.*;

import java.awt.*;

import java.awt.event.*;

import java.io.*;

import javax.servlet.*;

import org.apache.xalan.xslt.*;

public class xslservlet extends GenericServlet {

 public void service(ServletRequest request, ServletResponse response)

  throws ServletException, IOException {

  try {

   XSLTProcessor processor = XSLTProcessorFactory.getProcessor();

   processor.process(new XSLTInputSource("planets.xml"),

    new XSLTInputSource("planets.xsl"),

    new XSLTResultTarget("planets.html"));

  } catch(Exception e) {}

  .

  .

  .

Все, что осталось, — отправить HTML-документ обратно клиенту (листинг 10.14).

Листинг 10.14. Применение XSLT на сервере с сервлетами Java

import java.net.*;

import java.sql.*;

import java.awt.*;

import java.awt.event.*;

import java.io.*;

import javax.servlet.*;

import org.apache.xalan.xslt.*;

public class xslservlet extends GenericServlet {

 public void service(ServletRequest request, ServletResponse response)

  throws ServletException.IOException {

  response.setContentType("text/html");

  PrintWriter pw = response.getWriter();

  try {

   XSLTProcessor processor = XSLTProcessorFactory.getProcessor();

   processor.process(new XSLTInputSource("planets.xml"),

    new XSLTInputSource("planets.xsl"),

    new XSLTResultTarget("planets.html"));

  } catch(Exception e) {}

  FileReader filereader = new FileReader("planets.html");

  BufferedReader bufferedreader = new BufferedReader(filereader);

  String instring;

  while((instring = bufferedreader.readLine()) != null) {

   pw.println(instring);

  }

  filereader.close();

  pw.close();

 }

}

Теперь все сделано, результат показан на рис. 10.7 — HTML-документ, переданный из сервлета.

Рис. 10.7. Применение XSLT с сервлетами Java

На этом мы заканчиваем изучение работы с API процессоров XSLT в программном коде. Мы рассмотрели весьма объемный материал: как взаимодействовать с API процессоров XSLT из JavaScript и Java для процессоров MSXML, Xalan, XT, Saxon и Oracle, а также примеры выполнения XSLT-преобразований на web-серверах при помощи ASP, JSP и сервлетов Java.