KnigaRead.com/

Алексей Валиков - Технология XSLT

На нашем сайте KnigaRead.com Вы можете абсолютно бесплатно читать книгу онлайн Алексей Валиков, "Технология XSLT" бесплатно, без регистрации.
Перейти на страницу:

 -- Получаем CLOB-значение соответствующего преобразования

 SELECT STYLESHEET.CONTENT

 INTO stylesheetCLOB

 FROM STYLESHEET, SOURCE

 WHERE SOURCE.ID = sourceID AND SOURCE.STYLESHEETID = STYLESHEET.ID;


 -- Если хотя бы одно из значений - NULL, прерываем обработку

 -- и возвращаем NULL

 IF sourceCLOB IS NULL OR stylesheetCLOB IS NULL THEN

  RETURN NULL;

 END IF;


 -- Разбираем CLOB-значение входящего документа

 XMLPARSER.parseCLOB(parser, sourceCLOB);

 sourceXML := XMLPARSER.getDocument(parser);


 -- Разбираем CLOB-значение документа преобразования

 XMLPARSER.parseCLOB(parser, stylesheetCLOB);

 stylesheetXML := XMLPARSER.getDocument(parser);


 -- Инициализируем объект преобразования

 stylesheet := XSLPROCESSOR.newStylesheet(stylesheetXML, NULL);


 -- Выполняем преобразование

 XSLPROCESSOR.processXSL(processor, stylesheet, sourceXML, result);


 -- Освобождаем ресурсы

 XSLPROCESSOR.freeProcessor(processor);

 XMLPARSER.freeParser(parser);

 XMLDOM.freeDocument(sourceXML);

 XMLDOM.freeDocument(stylesheetXML);

 RETURN result;


 -- Обработка исключений

 EXCEPTION


  -- Если возникла исключительная ситуация

  WHEN OTHERS THEN

   -- Освобождаем ресурсы

   XSLPROCESSOR.freeProcessor(processor);

   XMLPARSER.freeParser(parser);

   XMLDOM.freeDocument(sourceXML);

   XMLDOM.freeDocument(stylesheetXML);


  -- Передаем исключение дальше

  RAISE;

END;

Представление обработанных документов теперь может быть описано совершенно элементарно.

Листинг 9.20. Представление PROCESSED_SOURCE

CREATE OR REPLACE VIEW PROCESSED_SOURCE AS

SELECT ID, PROCESS(ID) AS CONTENT

FROM SOURCE;

Продемонстрируем работу функции PROCESS и представления PROCESS_SOURCE на примере двух запросов.

Листинг 9.21. Запросы к таблице SOURCE и представлению PROCESSED_SOURCE

SQL> SELECT * FROM SOURCE;


ID  CONTENT       STYLESHEETID

--  ------------  ------------

1   <A>value</A>  1


SQL> SELECT * FROM PROCESSED_SOURCE;


ID CONTENT

-- -------------------------------------------------------

1  <?xml version = '1.0' encoding = 'UTF-8'?> <B>value</B>

Выполнение XSLT-преобразований в Java

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

Не стал исключением и XSLT. Можно смело сказать, что количество XSLT-средств, написанных на Java, превосходит половину вообще всех существующих в настоящее время XSLT-пакетов.

Для того чтобы продемонстрировать использование XSLT в Java, мы приведем два варианта одной и той же программы — серверного приложения (сервлета), которое по запросу клиента будет возвращать информацию о текущем HTTP-сеансе в формате HTML.

Первый вариант сервлета можно назвать "традиционным". В нем HTML-документ создается серией инструкций out.println(...), которые выводят в выходящий поток размеченную HTML-тегами информацию о текущем сеансе.

Листинг 9.22. Традиционный вариант сервлета

import javax.servlet.*;

import javax.servlet.http.*;

import java.io.*;

import java.util.*;


public class example extends HttpServlet {

 /**

 * Инициализация.

 */

 public void init(ServletConfig config) throws ServletException {

  super.init(config);

 }


 /**

 * Основной метод сервлета

 */

 public void service(HttpServletRequest request,

  HttpServletResponse response)

  throws ServletException, IOException {

  // Выставляем тип содержимого

  response.setContentType("text/html");

  // Инициализируем выходящий поток

  OutputStreamWriter osw =

   new OutputStreamWriter(response.getOutputStream());

  PrintWriter out = new PrintWriter (response.getOutputStream());

  // Выполняем вывод HTML-страницы

  out.println("<html>");

  // Выводим головную часть HTML-документа

  out.println(" <head>");

  out.println("  <title>Request information</title>");

  out.println(" </head>");

  // Выводим тело документа

  out.println(" <body>");

  // Выводим общую информацию о запросе

  out.println("  <h1>General information</h1>");

  out.println("  <table>");

  // Выводим имя сервера

  out.println("   <tr>");

  out.println("    <td>Server name</td>");

  out.println("    <td>" + request.getServerName() + "</td>");

  out.println("   </tr>");

  // Выводим порт сервера

  out.println("   <tr>");

  out.println("    <td>Server port</td>");

  out.println("    <td>" + request.getServerPort() + "</td>");

  out.println("   </tr>");

  // Выводим адрес запрашивающей стороны

  out.println("   <tr>");

  out.println("    <td>Remote address</td>") ;

  out.println("    <td>" + request.getRemoteAddr() + "</td>");

  out.println("   </tr>");

  // Выводим название протокола запроса

  out.println("   <tr>");

  out.println("    <td>Protocol</td>");

  out.println("    <td>" + request.getProtocol() + "</td>");

  out.println("   </tr>");

  // Выводим метод запроса

  out.println("   <tr>") ;

  out.println("    <td>Method</td>");

  out.println("    <td>" + request.getMethod() + "</td>");

  out.println("   </tr>");

  // Выводим URI запроса

  out.println("   <tr>");

  out.println("    <td>Request URI</td>");

  out.println("    <td>" + request.getRequestURI() + "</td>");

  out.println("   </tr>");

  // Выводим строку запроса

  out.println("   <tr>");

  out.println("    <td>Query String</td>");

  out.println("    <td>" + request.getQueryString() + "</td>");

  out.println("   </tr>");

  out.println("  </table>");

  // Выводим параметры запроса

  out.println("  <h1>Request parameters</h1>");

  out.println("  <table>");

  for (Enumeration e = request.getParameterNames();

   e.hasMoreElements();) {

   String name = e.nextElement().toString();

   String[] values = request.getParameterValues(name);

   for (int i=0; i < values.length; i++) {

    out.println("   <tr>");

    out.println("    <td>" + name + "</td>");

    out.println("    <td>" + values[i] + "</td>");

    out.println("   </tr>");

   }

  }

  out.println("  </table>");

  // Выводим параметры HTTP-сессии

  out.println("  <h1>Session parameters</h1>");

  out.println("  <table>");

  HttpSession session = request.getSession(true);

  String[] names = session.getValueNames();

  for (int i=0; i < names.length; i++) {

   String name = session.getValueNames()[i];

   out.println("   <tr>");

   out.println("    <td>" + name + "</td>");

   out.println("    <td>" +

   session.getValue(name).toString() + "</td>");

   out.println("   </tr>");

  }

  out.println("  </table>");

  // Выводим cookies

  response.addCookie(new Cookie("content", "apple jam"));

  out.println("  <h1>Cookies</h1>");

  out.println("  <table>");

  Cookie[] cookies = request.getCookies();

  for (int i=0; i < cookies.length; i++) {

   out.println("   <tr>");

   out.println("    <td>" + cookies[i].getName() + "</td>");

   out.println("    <td>" + cookies[i].getValue() + "</td>");

   out.println("   </tr>");

  }

  out.println("  </table>");

  out.println(" </body>");

  out.println("</html>");

  // Закрываем выходящий поток

  out.close();

 }

}

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

http://localhost/servlet/example?x=1&y=2&z=3&x=4&y=5&z=6

будет документ, аналогичный представленному на рис. 9.13.

Рис. 9.13. Результат обращения к сервлету

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

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

В этом варианте сервлета мы будем использовать Java-версию XML-библиотеки Oracle XDK (Oracle XML SDK, платформа разработки XML-приложений, созданная в Oracle Corp.). В данном примере из этой библиотеки мы будем использовать только XSLT-процессор (класс XSLProcessor) и реализацию DOM-модели XML-документа (класс XMLDocument). Во всем остальном мы будем полагаться на Java-реализацию стандартных интерфейсов объектной модели документа DOM, разработанной Консорциумом W3. DOM-интерфейсы позволят нам манипулировать XML-документом на уровне модели: создавать и включать друг в друга узлы элементов, текстовые узлы и так далее.

Перейти на страницу:
Прокомментировать
Подтвердите что вы не робот:*