F.62. xml2 — XPath-запросы и функциональность XSLT#

F.62. xml2 — XPath-запросы и функциональность XSLT

F.62. xml2 — XPath-запросы и функциональность XSLT #

Модуль xml2 предоставляет возможность выполнения запросов XPath и функциональность XSLT.

F.62.1. Уведомление об устаревании #

Начиная с PostgreSQL 8.3, в ядре сервера есть функциональность, связанная с XML, основанная на стандарте SQL/XML. Эта функциональность включает проверку синтаксиса XML и выполнение запросов XPath, что и делает данный модуль, а также предоставляет другие возможности. Однако, API не совместим с предыдущей версией. Планируется, что данный модуль будет удален в будущих версиях PostgreSQL в пользу нового стандартного API, поэтому рекомендуется попробовать преобразовать ваши приложения. Если вы обнаружите, что некоторая функциональность этого модуля недоступна в достаточной форме с использованием нового API, пожалуйста, опишите вашу проблему по адресу , чтобы недостаток мог быть устранен.

F.62.2. Описание функций #

Таблица F.37 показывает функции, предоставляемые этим модулем. Эти функции обеспечивают простой разбор XML и выполнение запросов XPath.

Таблица F.37. xml2 Функции

Функция

Описание

xml_valid ( document text ) → boolean

Анализирует указанный документ и возвращает true, если документ является правильно сформированным XML. (Примечание: это псевдоним для стандартной функции PostgreSQL xml_is_well_formed(). Название xml_valid() технически некорректно, поскольку правильность и правильность формы имеют разные значения в XML).

xpath_string ( document text, query text ) → text

Оценивает XPath-запрос в предоставленном документе и приводит результат к типу text.

xpath_number ( document text, query text ) → real

Оценивает XPath-запрос в предоставленном документе и приводит результат к типу real.

xpath_bool ( document text, query text ) → boolean

Оценивает XPath-запрос в предоставленном документе и приводит результат к типу boolean.

xpath_nodeset ( document text, query text, toptag text, itemtag text ) → text

Выполняет запрос к документу и оборачивает результат в XML-теги. Если результат является многозначным, вывод будет выглядеть так:

<toptag>
<itemtag>Value 1 which could be an XML fragment</itemtag>
<itemtag>Value 2....</itemtag>
</toptag>

Если toptag или itemtag является пустой строкой, соответствующий тег опускается.

xpath_nodeset ( document text, query text, itemtag text ) → text

Как xpath_nodeset(document, query, toptag, itemtag), но результат не включает toptag.

xpath_nodeset ( document text, query text ) → text

Как xpath_nodeset(document, query, toptag, itemtag), но результат не содержит оба тега.

xpath_list ( document text, query text, separator text ) → text

Оценивает запрос в документе и возвращает несколько значений, разделенных указанным разделителем, например Value 1,Значение 2,Значение 3, если delimiter равен ,.

xpath_list ( document text, query text ) → text

Это обертка для вышеприведенной функции, которая использует , в качестве разделителя.


F.62.3. xpath_table #

xpath_table(text key, text document, text relation, text xpaths, text criteria) returns setof record

xpath_table - это табличная функция, которая вычисляет набор XPath-запросов для каждого из набора документов и возвращает результаты в виде таблицы. Поле первичного ключа из исходной таблицы документов возвращается в качестве первого столбца результата, чтобы результат можно было легко использовать в соединениях. Параметры описаны в Таблица F.38.

Таблица F.38. xpath_table Параметры

ПараметрОписание
key

имя поля key — это просто поле, которое будет использоваться в качестве первого столбца выходной таблицы, то есть оно идентифицирует запись из которой была получена каждая выходная строка (см. примечание ниже о множественных значениях)

document

имя поля, содержащего XML документ

relation

имя таблицы или представления, содержащего документы

xpaths

одно или несколько выражений XPath, разделенных символом |

criteria

содержимое WHERE-предложения. Это не можно опустить, поэтому используйте true или 1=1, если нужно обработать все строки в отношении


Эти параметры (за исключением строк XPath) просто подставляются в обычный SQL-оператор SELECT, поэтому у вас есть некоторая гибкость. Оператор

ВЫБРАТЬ <ключ>, <документ> ИЗ <отношение> ГДЕ <условие>

таким образом, эти параметры могут быть любыми допустимыми в этих конкретных местах. Результатом этого SELECT должно быть возвращение ровно двух столбцов (если вы не попытаетесь перечислить несколько полей для ключа или документа). Остерегайтесь, что этот упрощенный подход требует проверки любых пользовательских значений, чтобы избежать атак SQL-инъекций.

Функцию необходимо использовать в выражении FROM, с указанием предложения AS для определения выходных столбцов; например

SELECT * FROM
xpath_table('article_id',
            'article_xml',
            'articles',
            '/article/author|/article/pages|/article/title',
            'date_entered > ''2003-01-01'' ')
AS t(article_id integer, author text, page_count integer, title text);

Предложение AS определяет имена и типы столбцов в выходной таблице. Первый столбец - это поле key, а остальные соответствуют запросам XPath. Если количество запросов XPath больше, чем количество столбцов с результатами, дополнительные запросы будут проигнорированы. Если количество столбцов с результатами больше, чем количество запросов XPath, дополнительные столбцы будут содержать значение NULL.

Обратите внимание, что в этом примере столбец результата page_count определен как целое число. Функция работает внутренне с строковыми представлениями, поэтому, когда вы указываете, что хотите получить целое число в выводе, она берет строковое представление результата XPath и использует функции ввода PostgreSQL для преобразования его в целое число (или в любой другой тип, указанный в предложении AS). Если это невозможно сделать, возникнет ошибка - например, если результат пустой. Поэтому, если вы считаете, что ваши данные могут содержать проблемы, вам может быть удобнее использовать тип столбца text.

Вызывающий оператор SELECT не обязательно должен быть просто SELECT * — он может ссылаться на выходные столбцы по имени или объединять их с другими таблицами. Функция создает виртуальную таблицу, с которой вы можете выполнять любые операции (например, агрегацию, соединение, сортировку и т. д.). Так что мы также можем иметь:

SELECT t.title, p.fullname, p.email
FROM xpath_table('article_id', 'article_xml', 'articles',
                 '/article/title|/article/author/@id',
                 'xpath_string(article_xml,''/article/@date'') > ''2003-03-20'' ')
       AS t(article_id integer, title text, author_id integer),
     tblPeopleInfo AS p
WHERE t.author_id = p.person_id;

как более сложный пример. Конечно, вы можете обернуть все это в представление для удобства.

F.62.3.1. Многозначные результаты #

Функция xpath_table предполагает, что результаты каждого запроса XPath могут быть многозначными, поэтому количество строк, возвращаемых функцией, может не совпадать с количеством входных документов. Первая строка содержит первый результат каждого запроса, вторая строка - второй результат каждого запроса. Если один из запросов имеет меньше значений, чем остальные, вместо них будут возвращены значения null.

В некоторых случаях пользователь будет знать, что данный XPath-запрос вернет только один результат (например, уникальный идентификатор документа) - если он используется вместе с XPath-запросом, возвращающим несколько результатов, то единственное значение будет отображаться только в первой строке результата. Решение этой проблемы заключается в использовании ключевого поля в качестве части соединения с более простым XPath-запросом. В качестве примера:

CREATE TABLE test (
    id int PRIMARY KEY,
    xml text
);

INSERT INTO test VALUES (1, '<doc num="C1">
<line num="L1"><a>1</a><b>2</b><c>3</c></line>
<line num="L2"><a>11</a><b>22</b><c>33</c></line>
</doc>');

INSERT INTO test VALUES (2, '<doc num="C2">
<line num="L1"><a>111</a><b>222</b><c>333</c></line>
<line num="L2"><a>111</a><b>222</b><c>333</c></line>
</doc>');

SELECT * FROM
  xpath_table('id','xml','test',
              '/doc/@num|/doc/line/@num|/doc/line/a|/doc/line/b|/doc/line/c',
              'true')
  AS t(id int, doc_num varchar(10), line_num varchar(10), val1 int, val2 int, val3 int)
WHERE id = 1 ORDER BY doc_num, line_num

 id | doc_num | line_num | val1 | val2 | val3
----+---------+----------+------+------+------
  1 | C1      | L1       |    1 |    2 |    3
  1 |         | L2       |   11 |   22 |   33

Чтобы получить doc_num на каждой строке, решением является использование двух вызовов xpath_table и соединение результатов:

SELECT t.*,i.doc_num FROM
  xpath_table('id', 'xml', 'test',
              '/doc/line/@num|/doc/line/a|/doc/line/b|/doc/line/c',
              'true')
    AS t(id int, line_num varchar(10), val1 int, val2 int, val3 int),
  xpath_table('id', 'xml', 'test', '/doc/@num', 'true')
    AS i(id int, doc_num varchar(10))
WHERE i.id=t.id AND i.id=1
ORDER BY doc_num, line_num;

 id | line_num | val1 | val2 | val3 | doc_num
----+----------+------+------+------+---------
  1 | L1       |    1 |    2 |    3 | C1
  1 | L2       |   11 |   22 |   33 | C1
(2 rows)

F.62.4. Функции XSLT #

Следующие функции доступны, если установлен libxslt:

F.62.4.1. xslt_process #

xslt_process(text document, text stylesheet, text paramlist) returns text

Эта функция применяет XSL-шаблон к документу и возвращает преобразованный результат. paramlist - это список присваиваний параметров, которые будут использоваться в преобразовании, указанный в форме a=1,b=2. Обратите внимание, что разбор параметров очень простой: значения параметров не могут содержать запятые!

Существует также двухпараметрическая версия функции xslt_process, которая не передает никаких параметров для преобразования.

F.62.5. Автор #

John Gray

Разработка этого модуля была спонсирована компанией Torchbox Ltd. (www.torchbox.com). Он имеет ту же лицензию BSD, что и PostgreSQL.