' <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
.
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;
Представление обработанных документов теперь может быть описано совершенно элементарно.
CREATE OR REPLACE VIEW PROCESSED_SOURCE AS
SELECT ID, PROCESS(ID) AS CONTENT
FROM SOURCE;
Продемонстрируем работу функции PROCESS
и представления PROCESS_SOURCE
на примере двух запросов.
SQL> SELECT * FROM SOURCE;