Работа с XML-данными
Greengage DB поддерживает тип данных XML для хранения и обработки XML-данных.
СУБД проверяет корректность структуры XML при вставке, позволяя хранить как полноценные XML-документы, так и отдельные фрагменты XML-содержимого.
Встроенные функции и операторы обеспечивают удобное извлечение, преобразование и представление XML-данных непосредственно в SQL-запросах.
Для выполнения команд, описанных в следующих разделах, подключитесь к мастер-хосту Greengage DB с помощью psql, как описано в статье Подключение к Greengage DB с использованием psql.
Создайте новую базу данных и подключитесь к ней:
CREATE DATABASE marketplace;
\c marketplace
Обзор
Greengage DB поддерживает работу с XML-данными с помощью типа данных XML.
Он позволяет хранить, запрашивать и обрабатывать иерархические или полуструктурированные данные в базе данных наряду с реляционными таблицами.
Основные возможности включают:
-
Хранение XML-данных
Тип
XMLможет хранить полные XML-документы или фрагменты XML-содержимого непосредственно в столбцах таблиц. XML-документ должен иметь ровно один корневой элемент, тогда как XML-содержимое может включать несколько элементов верхнего уровня. -
Запросы к XML-данным и их фильтрация
Такие функции, как
xpath()иxpath_exists(), позволяют извлекать данные и проверять наличие определенных элементов. Greengage DB поддерживает только выражения XPath 1.0. -
Формирование XML-данных
Такие функции, как
xmlelement(),xmlroot()иxmlcomment(), позволяют создавать XML-структуры из данных SQL и форматировать результаты запросов как XML-документы для клиентских приложений. -
Сериализация и десериализация XML-данных
xmlparse()преобразует текст в XML-значение, аxmlserialize()выполняет обратную операцию — преобразует XML в текстовое представление, удобное для передачи между приложениями или сохранения вне базы данных.
Кодировка символов
Убедитесь, что при обмене XML-данными между клиентом и сервером используются корректные кодировки символов:
-
В текстовом режиме Greengage DB автоматически преобразует символьные данные между кодировками клиента и сервера. Это также касается XML-значений, поэтому любое объявление кодировки внутри XML-документа после преобразования может больше не соответствовать фактической кодировке. Для корректной обработки Greengage DB игнорирует объявления кодировки при чтении входных XML-данных и предполагает, что данные имеют текущую кодировку сервера. Поэтому клиентские приложения должны отправлять XML-данные в текущей клиентской кодировке или предварительно преобразовать их в эту кодировку перед отправкой на сервер. Когда клиент получает XML-значения с сервера, объявление кодировки не включается в результат; клиент должен интерпретировать возвращенные данные как находящиеся в текущей клиентской кодировке.
-
В двоичном режиме преобразование кодировок не выполняется. Объявления кодировки в XML учитываются, а при их отсутствии данные интерпретируются как UTF-8 (в соответствии со стандартом XML). При выводе объявление кодировки включается, если только кодировка клиента не UTF-8.
Подробнее о текстовом и двоичном режимах смотрите в разделе документации PostgreSQL о функциях libpq для исполнения команд.
Обработка XML становится более быстрой и надежной, если XML-данные, клиент и сервер используют одну и ту же кодировку. Поскольку Greengage DB обрабатывает XML в UTF-8, рекомендуется использовать UTF-8 в качестве кодировки сервера.
Доступ к значениям XML
Тип данных XML не поддерживает операторы сравнения (например, <, > или =), поскольку не существует стандартного способа сравнивать два XML-документа.
Из-за этого нельзя выполнять поиск строк, напрямую сравнивая XML-столбцы с определенными значениями.
Чтобы идентифицировать XML-строки, добавьте отдельное поле-ключ, например идентификатор (ID).
При необходимости значения XML можно привести к типу TEXT для сравнения, однако в этом случае сравнивается только текстовое представление, а не структура XML.
Поскольку отсутствуют операторы сравнения, для XML-столбцов нельзя создавать индексы напрямую.
Поиск можно ускорить, создав индекс на производном выражении, например на приведенном к тексту XML-значении или на результате XPath-запроса.
Пример создания и использования таких индексов см. в разделе Индексация XML-данных.
Хранение XML-данных
Создание таблицы для XML-данных
В этом примере таблица customer_profiles содержит два столбца типа XML — один для полных XML-документов (profile), другой для фрагментов XML-содержимого (details):
CREATE TABLE customer_profiles
(
id SERIAL,
profile XML,
details XML
)
DISTRIBUTED BY (id);
Узнайте больше про определение таблиц в статье Обзор таблиц.
Загрузка XML-данных
После создания таблицы можно вставлять XML-данные с помощью функции xmlparse().
Функция xmlparse() преобразует текст в значение типа XML и позволяет указать, является ли входной текст полным документом (document) или фрагментом XML-содержимого (content).
В примере ниже в столбец profile добавляются полные XML-документы с информацией о клиенте, а в столбец details — фрагменты XML с верхнеуровневым элементом tags, содержащим вложенные элементы:
INSERT INTO customer_profiles (profile, details)
VALUES (xmlparse(document
'<customer id="c001">
<name>Alice Johnson</name>
<email>alice@example.com</email>
<active>true</active>
<registered>2020-01-15</registered>
</customer>'
),
xmlparse(content
'<tags>
<membership>premium</membership>
<membership>newsletter</membership>
<region>US</region>
</tags>'
)),
(xmlparse(document
'<customer id="c002">
<name>Bob Smith</name>
<email>bob@example.com</email>
<active>false</active>
<registered>2019-06-30</registered>
</customer>'
),
xmlparse(content
'<tags>
<membership>trial</membership>
<region>EU</region>
</tags>'
)),
(xmlparse(document
'<customer id="c003">
<name>Charlie Brown</name>
<email>charlie@example.com</email>
<active>true</active>
</customer>'
),
NULL);
Greengage DB выполняет проверку XML-данных на корректность (well-formed) при вставке и обновлении. Проверки DTD и XML Schema (XSD) не поддерживаются. Если XML некорректен, операция отклоняется и возвращается ошибка, как показано ниже. Проверку соответствия схеме следует выполнять на уровне приложения.
INSERT INTO customer_profiles (profile, details)
VALUES (xmlparse(document
'<customer>
<name>John Doe</name>
<email>john@example.com</email>'
),
NULL);
Операция вызывает следующую ошибку:
ERROR: invalid XML document (seg1 slice1 192.168.1.30:10001 pid=2537)
DETAIL: line 1: Premature end of data in tag customer line 1
<customer><name>John Doe</name><email>john@example.com</email>
^
Greengage DB также позволяет преобразовывать XML-данные перед их загрузкой в таблицы.
Пример того, как с помощью XSLT или Python преобразовать исходные XML-данные и загрузить их через gpfdist или gpload, смотрите в статье Трансформация внешних данных.
Запросы к XML-данным и их фильтрация
Основная функция для извлечения данных из столбцов XML в Greengage DB — xpath().
Она возвращает массив всех узлов, соответствующих заданному выражению XPath.
Чтобы получить одно значение, можно выбрать первый элемент с помощью [1] и привести его к типу TEXT с помощью ::TEXT.
Например, выполните следующий SQL-запрос, чтобы получить элементы /customer/name и /customer/email из столбца profile:
SELECT (xpath('/customer/name/text()', profile))[1]::TEXT AS name,
(xpath('/customer/email/text()', profile))[1]::TEXT AS email
FROM customer_profiles;
Результат должен выглядеть так:
name | email ---------------+--------------------- Alice Johnson | alice@example.com Bob Smith | bob@example.com Charlie Brown | charlie@example.com (3 rows)
Аналогичный подход применяется к фрагментам XML.
В этом примере также показано извлечение элемента /tags/region из столбца details:
SELECT (xpath('/customer/name/text()', profile))[1]::TEXT AS name,
(xpath('/customer/email/text()', profile))[1]::TEXT AS email,
(xpath('/tags/region/text()', details))[1]::TEXT AS region
FROM customer_profiles;
Результат выглядит следующим образом:
name | email | region ---------------+---------------------+-------- Charlie Brown | charlie@example.com | Alice Johnson | alice@example.com | US Bob Smith | bob@example.com | EU (3 rows)
Вы можете отфильтровать строки по наличию элемента с помощью xpath_exists():
SELECT (xpath('/customer/name/text()', profile))[1]::TEXT AS name,
(xpath('/customer/registered/text()', profile))[1]::TEXT AS registered
FROM customer_profiles
WHERE xpath_exists('/customer/registered', profile);
Результат:
name | registered ---------------+------------ Alice Johnson | 2020-01-15 Bob Smith | 2019-06-30 (2 rows)
Подробнее о получении строк из таблиц и представлений см. в статье Обзор команды SELECT.
Индексация XML-данных
При работе с большими таблицами поиск по XML-значениям может быть медленным, так как столбцы XML не поддерживают прямые операторы сравнения.
По этой причине индексы нельзя создавать для столбцов типа XML.
Для ускорения поиска можно создать индекс по выражению на производном значении, например на результате функции xpath(), приведенном к типу TEXT.
Поскольку индексы по выражениям поддерживаются только планировщиком Postgres, отключите оптимизатор запросов GPORCA:
SET optimizer = off;
Установите опцию enable_seqscan в значение off:
SET enable_seqscan = off;
Затем создайте индекс на элемент /customer/name в XML-столбце profile:
CREATE INDEX customer_name_gin_idx
ON customer_profiles USING gin (cast(xpath('string(/customer/name)', profile) AS TEXT[]));
Обновите статистику таблицы:
ANALYZE customer_profiles;
После этого можно использовать индексированное выражение в запросе.
Например, чтобы найти клиента по имени Charlie Brown:
EXPLAIN (COSTS OFF)
SELECT *
FROM customer_profiles
WHERE cast(xpath('string(/customer/name)', profile) AS TEXT[]) @> ARRAY['Charlie Brown'];
Вывод показывает, что запрос использует индексированное выражение:
QUERY PLAN
-----------------------------------------------------------------------------------------------------------------------------------
Gather Motion 4:1 (slice1; segments: 4)
-> Bitmap Heap Scan on customer_profiles
Recheck Cond: ((xpath('string(/customer/name)'::text, profile, '{}'::text[]))::text[] @> '{"Charlie Brown"}'::text[])
-> Bitmap Index Scan on customer_name_gin_idx
Index Cond: ((xpath('string(/customer/name)'::text, profile, '{}'::text[]))::text[] @> '{"Charlie Brown"}'::text[])
Optimizer: Postgres query optimizer
(6 rows)
Формирование XML-данных
CREATE TABLE customers
(
id int,
name text,
email text
)
WITH (appendoptimized = true)
DISTRIBUTED BY (id);
INSERT INTO customers(id, name, email)
VALUES (1, 'Alice Johnson', 'alice@example.com'),
(2, 'Bob Smith', 'bob@example.com'),
(3, 'Charlie Brown', 'charlie@example.com');
Greengage DB предоставляет набор функций для формирования XML-контента из SQL-данных. Эти функции особенно удобны для форматирования результатов запросов в XML-документы для обработки в клиентских приложениях.
Используйте функцию xmlelement() для создания XML-элемента с указанным именем, атрибутами и содержимым:
SELECT xmlelement(name customer, name) AS xml_customer
FROM customers;
Результат выглядит следующим образом:
xml_customer ------------------------------------ <customer>Charlie Brown</customer> <customer>Alice Johnson</customer> <customer>Bob Smith</customer> (3 rows)
xmlelement() также поддерживает создание вложенных элементов и добавление атрибутов с помощью xmlattributes():
SELECT xmlelement(
name customer,
xmlattributes(id AS id),
xmlelement(name name, name),
xmlelement(name email, email)
) AS xml_customer
FROM customers;
Результат должен выглядеть так:
xml_customer ------------------------------------------------------------------------------------------ <customer id="3"><name>Charlie Brown</name><email>charlie@example.com</email></customer> <customer id="1"><name>Alice Johnson</name><email>alice@example.com</email></customer> <customer id="2"><name>Bob Smith</name><email>bob@example.com</email></customer> (3 rows)
Чтобы преобразовать значение XML в текстовое представление, пригодное для экспорта или сохранения, используйте xmlserialize():
SELECT xmlserialize(
content xmlelement(
name customer,
xmlattributes(id AS id),
xmlelement(name name, name),
xmlelement(name email, email)
) as TEXT
) AS xml_text
FROM customers;
Результат:
xml_text ------------------------------------------------------------------------------------------ <customer id="1"><name>Alice Johnson</name><email>alice@example.com</email></customer> <customer id="3"><name>Charlie Brown</name><email>charlie@example.com</email></customer> <customer id="2"><name>Bob Smith</name><email>bob@example.com</email></customer> (3 rows)
См. раздел Создание XML-контента, чтобы узнать больше о функциях для построения XML, и Экспорт таблиц в XML — о генерации XML из таблиц и запросов.
Справочник: функции и предикаты для работы с XML
Сериализация/десериализация XML
xmlparse()
Функция: xmlparse({ document | content } <value>)
Тип возвращаемого значения: XML
Создает XML из символьных данных.
Первый аргумент задает тип <value>:
-
document— XML-документ. -
content— фрагмент XML-содержимого.
Пример:
SELECT xmlparse(document
'<customer id="c001">
<name>Alice Johnson</name>
<email>alice@example.com</email>
</customer>'
);
Результат:
xmlparse
-----------------------------------------------------
<customer id="c001"> +
<name>Alice Johnson</name> +
<email>alice@example.com</email>+
</customer>
(1 row)
Вы также можете использовать ::XML — преобразование, специфичное для PostgreSQL:
SELECT '<customer id="c001">
<name>Alice Johnson</name>
<email>alice@example.com</email>
</customer>'::XML;
Обратите внимание, что приведение к типу XML не проверяет входные значения на соответствие объявлению типа документа (Document Type Declaration, DTD) и другим разновидностям схем XML.
xmlserialize()
Функция: xmlserialize({ document | content } <value> AS <type>)
Тип возвращаемого значения: <type>
Создает строковое значение из XML.
Первый аргумент определяет тип <value>:
-
document— XML-документ. -
content— фрагмент XML-содержимого.
<type> может быть типом данных CHARACTER, CHARACTER VARYING или TEXT.
Пример:
SELECT xmlserialize(content xmlelement(name customer,
xmlelement(name name, 'Alice Johnson'),
xmlelement(name email, 'alice@example.com'))
as TEXT
) AS xml_text;
Результат:
xml_text --------------------------------------------------------------------------------- <customer><name>Alice Johnson</name><email>alice@example.com</email></customer> (1 row)
Создание XML-контента
Двоичные значения (тип BYTEA) кодируются в XML в соответствии с параметром xmlbinary — base64 или hex.
Это применяется, когда функции, такие как xmlelement() или xmlforest(), преобразуют BYTEA в XML.
Выбор способа кодирования зависит от требований клиентского приложения.
xmlcomment()
Функция: xmlcomment(<text>)
Тип возвращаемого значения: XML
Создает XML-комментарий с указанным текстом.
Пример:
SELECT xmlcomment('Hello, world!');
Результат:
xmlcomment ---------------------- <!--Hello, world!--> (1 row)
xmlelement()
Функция: xmlelement(name <name> [, xmlattributes(<value> [AS <attname>] [, …])] [, <content>, …])
Тип возвращаемого значения: XML
Создает XML-элемент с заданным именем, атрибутами и содержимым.
Пример 1:
SELECT xmlelement(name email, 'alice@example.com');
Результат:
xmlelement ---------------------------------- <email>alice@example.com</email> (1 row)
Пример 2:
SELECT xmlelement(name customer,
xmlattributes('c001' AS id),
xmlelement(name name, 'Alice Johnson'),
xmlelement(name email, 'alice@example.com'));
Результат:
xmlelement ------------------------------------------------------------------------------------------- <customer id="c001"><name>Alice Johnson</name><email>alice@example.com</email></customer> (1 row)
xmlforest()
Функция: xmlforest(<content> [AS <name>] [, …])
Тип возвращаемого значения: XML
Создает последовательность XML-элементов с заданными именами и содержимым.
Пример:
SELECT xmlforest('Alice Johnson' AS name,
'alice@example.com' AS email,
'true' AS active);
Результат:
xmlforest --------------------------------------------------------------------------------- <name>Alice Johnson</name><email>alice@example.com</email><active>true</active> (1 row)
xmlroot()
Функция: xmlroot(<xml>, version <text> | no value [, standalone yes|no|no value])
Тип возвращаемого значения: XML
Изменяет свойства корневого узла XML-значения.
Если указан аргумент version, он обновляет соответствующее значение в объявлении версии корневого узла.
Если указан аргумент standalone, он обновляет значение атрибута standalone в объявлении корневого узла.
Пример:
SELECT xmlroot(xmlparse(document '<?xml version="1.1"?><content>abc</content>'),
version '1.0', standalone yes);
Результат:
xmlroot -------------------------------------------------------------- <?xml version="1.0" standalone="yes"?><content>abc</content> (1 row)
xmlagg()
Функция: xmlagg(<xml>)
Тип возвращаемого значения: XML
Агрегирует XML-значения из нескольких строк в одно XML-значение путем их объединения.
Пример:
CREATE TABLE customers
(
id SERIAL,
details XML
)
WITH (appendoptimized = true)
DISTRIBUTED BY (id);
INSERT INTO customers(details)
VALUES (xmlelement(name customer, xmlelement(name name, 'Alice Johnson'))),
(xmlelement(name customer, xmlelement(name name, 'Charlie Brown')));
SELECT xmlagg(details)
FROM customers;
Результат:
xmlagg ------------------------------------------------------------------------------------------------ <customer><name>Alice Johnson</name></customer><customer><name>Charlie Brown</name></customer> (1 row)
Предикаты XML
Параметр xmloption определяет, следует ли интерпретировать текст как XML-документ или как фрагмент XML-содержимого.
Он влияет на работу таких функций, как xml_is_well_formed(), определяя, является ли XML корректным как полный документ или как фрагмент содержимого.
IS DOCUMENT / IS NOT DOCUMENT
Выражения: <xml> IS DOCUMENT, <xml> IS NOT DOCUMENT
Тип возвращаемого значения: BOOLEAN
Определяют, является ли значение XML документом или фрагментом содержимого.
Пример:
SELECT xmlparse(document
'<customer id="c001">
<name>Alice Johnson</name>
<email>alice@example.com</email>
</customer>'
) IS DOCUMENT AS is_doc;
Результат:
is_doc -------- t (1 row)
xmlexists()
Функция: xmlexists(<text> PASSING [BY REF] <xml> [BY REF])
Тип возвращаемого значения: BOOLEAN
Определяет, возвращает ли указанное XPath-выражение какие-либо узлы из заданного XML-значения.
Возвращает true, если найдены совпадающие узлы, false, если узлы не найдены, и null, если любой из аргументов равен null.
Пример:
SELECT xmlexists('//customer[name="Bob Smith"]' PASSING BY REF
'
<customers>
<customer>
<name>Bob Smith</name>
</customer>
</customers>');
Результат:
xmlexists ----------- t (1 row)
xml_is_well_formed()
Функция: xml_is_well_formed(<text>)
Тип возвращаемого значения: BOOLEAN
Проверяет, является ли текстовая строка корректно сформированным XML-документом или фрагментом содержимого.
Поведение зависит от параметра конфигурации xmloption: при значении document проверяется корректность полного XML-документа, а при значении content — корректность фрагмента XML-содержимого.
Пример 1:
SELECT xml_is_well_formed('<customer><name>Alice Johnson</name></customer>');
Результат:
xml_is_well_formed -------------------- t (1 row)
Пример 2:
SELECT xml_is_well_formed('<customer><name>Alice Johnson</name>');
Результат:
xml_is_well_formed -------------------- f (1 row)
xml_is_well_formed_document()
Функция: xml_is_well_formed_document(<text>)
Тип возвращаемого значения: BOOLEAN
Проверяет, является ли текстовая строка корректно сформированным XML-документом.
Пример:
SELECT xml_is_well_formed_document('<customer><name>Bob Smith</name></customer>');
Результат:
xml_is_well_formed_document ----------------------------- t (1 row)
xml_is_well_formed_content()
Функция: xml_is_well_formed_content(<text>)
Тип возвращаемого значения: BOOLEAN
Проверяет, является ли текстовая строка корректно сформированным фрагментом XML-содержимого.
Пример:
SELECT xml_is_well_formed_content('<name>Charlie Brown</name>');
Результат:
xml_is_well_formed_content ---------------------------- t (1 row)
Обработка XML
xpath()
Функция: xpath(<xpath>, <xml> [, <nsarray>])
Тип возвращаемого значения: XML[]
Возвращает массив XML-значений, соответствующих выражению XPath.
Если выражение XPath возвращает скалярное значение, xpath() возвращает массив из одного элемента.
Второй аргумент должен представлять собой корректно сформированный XML-документ с одним корневым элементом.
Необязательный третий аргумент — это массив сопоставлений пространств имен.
Это должен быть двумерный текстовый массив, где каждый подмассив содержит ровно два элемента: первый — псевдоним пространства имен, второй — URI пространства имен.
Псевдонимы не обязаны совпадать с теми, что используются в самом XML-документе; они локальны для функции xpath().
Пример:
SELECT (xpath('/customer/email/text()',
'<customer>
<name>Alice Johnson</name>
<email>alice@example.com</email>
</customer>'
))[1]::TEXT AS email;
Результат:
email ------------------- alice@example.com (1 row)
xpath_exists()
Функция: xpath_exists(<xpath>, <xml> [, <nsarray>])
Тип возвращаемого значения: BOOLEAN
Определяет, существуют ли элементы, соответствующие выражению XPath.
Эта функция работает аналогично предикату xmlexists(), но дополнительно поддерживает необязательный аргумент сопоставления пространств имен.
Пример 1:
SELECT xpath_exists('/customer/name',
'<customer>
<name>Alice Johnson</name>
<email>alice@example.com</email>
</customer>');
Результат:
xpath_exists -------------- t (1 row)
Пример 2:
SELECT xpath_exists('/cust:customer/cust:name',
'<cust:customer xmlns:cust="https://example.com/other">
<cust:name>Alice Johnson</cust:name>
<cust:email>alice@example.com</cust:email>
</cust:customer>',
ARRAY [ARRAY ['cust', 'https://example.com/customer']]);
Результат:
xpath_exists -------------- f (1 row)
Экспорт таблиц в XML
table_to_xml()
Функция: table_to_xml(<table> REGCLASS, <nulls> BOOLEAN, <tableforest> BOOLEAN, <targetns> TEXT)
Тип возвращаемого значения: XML
Создает XML-представление таблицы, указанной параметром <table>.
Другие аргументы:
-
Параметр
<nulls>определяет, следует ли включать значенияnullв вывод. -
Если параметр
<tableforest>имеет значениеfalse, результирующий XML-документ будет содержать дополнительные узлы<row>. -
Параметр
<targetns>определяет пространство имен XML. Если вам не нужно задавать пространство имен, передайте пустую строку.
Пример:
CREATE TABLE customers
(
id int,
name text,
email text
)
WITH (appendoptimized = true)
DISTRIBUTED BY (id);
INSERT INTO customers(id, name, email)
VALUES (1, 'Alice Johnson', 'alice@example.com'),
(2, 'Bob Smith', 'bob@example.com'),
(3, 'Charlie Brown', 'charlie@example.com');
SELECT table_to_xml('customers', true, false, '');
Результат:
table_to_xml
-------------------------------------------------------------------
<customers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">+
+
<row> +
<id>2</id> +
<name>Bob Smith</name> +
<email>bob@example.com</email> +
</row> +
+
<row> +
<id>3</id> +
<name>Charlie Brown</name> +
<email>charlie@example.com</email> +
</row> +
+
<row> +
<id>1</id> +
<name>Alice Johnson</name> +
<email>alice@example.com</email> +
</row> +
+
</customers> +
(1 row)
query_to_xml()
Функция: query_to_xml(<query> TEXT, <nulls> BOOLEAN, <tableforest> BOOLEAN, <targetns> TEXT)
Тип возвращаемого значения: XML
Создает XML-представление результатов SQL-запроса, указанного в параметре <query>.
В отличие от table_to_xml(), позволяет преобразовывать результат произвольного запроса, а не только одной таблицы.
Смотрите также: table_to_xml().
Пример:
SELECT query_to_xml('SELECT id, name FROM customers', true, false, '');
Результат:
query_to_xml
---------------------------------------------------------------
<table xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">+
+
<row> +
<id>3</id> +
<name>Charlie Brown</name> +
</row> +
+
<row> +
<id>1</id> +
<name>Alice Johnson</name> +
</row> +
+
<row> +
<id>2</id> +
<name>Bob Smith</name> +
</row> +
+
</table> +
(1 row)
cursor_to_xml()
Функция: cursor_to_xml(<cursor> REFCURSOR, <count> INTEGER, <nulls> BOOLEAN, <tableforest> BOOLEAN, <targetns> TEXT)
Тип возвращаемого значения: XML
Создает XML-представление строк, извлеченных из указанного курсора (<cursor>).
Параметр <count> определяет, сколько строк нужно извлечь.
Функция рекомендуется для работы с большими наборами данных, так как обрабатывает их поэтапно, а не формирует весь XML-документ целиком в памяти.
Смотрите также: table_to_xml().
Пример:
BEGIN;
DECLARE customer_data_cur CURSOR FOR
SELECT id, name
FROM customers
ORDER BY id;
SELECT cursor_to_xml('customer_data_cur' ::refcursor, 2, true, true, '');
CLOSE customer_data_cur;
COMMIT;
Результат:
cursor_to_xml
-------------------------------------------------------------
<row xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">+
<id>1</id> +
<name>Alice Johnson</name> +
</row> +
+
<row xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">+
<id>2</id> +
<name>Bob Smith</name> +
</row> +
+
(1 row)