Книга: Технология XSLT

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

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

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

На этот раз в качестве целевой платформы будет использоваться база данных Oracle 8i, которая обеспечивает поддержку XSLT несколькими встроенными пакетами: XMLDOM, XMLPARSER и XSLPROCESSOR.

Представим себе следующую схему элементарной БД (рис. 9.12):


Рис. 9.12. Схема простой базы данных

Таблица STYLESHEET содержит XSLT-преобразования, которые хранятся в полях CONTENT, поле ID указывает уникальный идентификатор каждого из них.

Таблица SOURCE содержит XML-документы (поле CONTENT), каждому из которых соответствует некоторое преобразование (внешний ключ STYLESHEETID). Нашей задачей будет создание представления, в котором документы, хранящиеся в таблице SOURCE, будут обрабатываться соответствующими преобразованиями из таблицы STYLESHEET.

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

Листинг 9.15. Создание схемы БД

-- Создаем таблицу stylesheet
CREATE TABLE STYLESHEET
 (ID     INTEGER NOT NULL,
 CONTENT CLOB NULL);
-- Создаем первичный ключ таблицы STYLESHEET
ALTER TABLE STYLESHEET
 ADD (PRIMARY KEY (ID));
-- Создаем таблицу SOURCE
CREATE TABLE SOURCE
 (ID          INTEGER NOT NULL,
 CONTENT      CLOB NULL,
 STYLESHEETID INTEGER NOT NULL);
-- Создаем первичный ключ таблицы SOURCE
ALTER TABLE SOURCE
 ADD (PRIMARY KEY (ID));
-- Создаем внешний ключ, связывающий таблицы SOURCE и STYLESHEET
ALTER TABLE SOURCE
 ADD (FOREIGN KEY (STYLESHEETID) REFERENCES STYLESHEET);

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

Листинг 9.16. Преобразование

<xsl:stylesheet
 version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:template match="A">
  <B><xsl:value-of select="."/></B>
 </xsl:template>
</xsl:stylesheet>

Листинг 9.17. Обрабатываемый документ

<A>value</A>

Листинг 9.18. SQL-скрипт, загружающий документ и преобразование в БД

-- Сохраняем преобразование
INSERT INTO STYLESHEET VALUES
(1, '<xsl:stylesheet                                     '||
    ', version="1.0"                                     '||
    '  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> '||
    '  <xsl:template match="A">                          '||
    '   <B><xsl:value-of select="."/></B>                '||
    '   </xsl:template>                                  '||
    '  </xsl:stylesheet>                                 ');
-- Сохраняем документ
INSERT INTO SOURCE VALUES
(1, '<A>value</A>', 1);

Для того чтобы выполнять преобразования в SELECT-выражении представления таблицы SOURCE, мы напишем функцию PROCESS, которая будет возвращать результат обработки документа с уникальным идентификатором, заданным параметром sourceID.

Листинг 9.19. Функция PROCESS

CREATE OR REPLACE FUNCTION PROCESS (sourceID NUMBER) RETURN VARCHAR2 IS
 -- Инициализация XML-парсера и XSLT-процессора
 parser XMLPARSER.Parser := XMLPARSER.newParser;
 processor XSLPROCESSOR.Processor := XSLPROCESSOR.newProcessor;
 -- Переменные для CLOB-значений входящего документа и преобразования
 sourceCLOB CLOB;
 stylesheetCLOB CLOB;
 -- Переменные для DOM-объектов входящего документа и преобразования
 sourceXML XMLDOM.DOMDocument;
 stylesheetXML XMLDOM.DOMDocument;
 -- Переменная для объекта преобразования
 stylesheet XSLPROCESSOR.Stylesheet;
 -- Переменная результата
 result varchar2(32767);
BEGIN
 -- Получаем CLOB-значение входящего документа в переменную sourceCLOB
 SELECT CONTENT
 INTO sourceCLOB
 FROM SOURCE
 WHERE ID = sourceID;
 -- Получаем 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>

Оглавление книги


Генерация: 0.045. Запросов К БД/Cache: 0 / 0
поделиться
Вверх Вниз