9.15. Функции XML#
9.15. Функции XML #
Функции и функциональные выражения, описанные в этом разделе, работают с значениями типа xml
. См. Раздел 8.13 для получения информации о типе xml
. Функциональные выражения xmlparse
и xmlserialize
для преобразования в и из типа xml
документированы там, а не в этом разделе.
Использование большинства этих функций требует, чтобы Tantor BE был собран с использованием configure --with-libxml
.
9.15.1. Производство XML-контента #
Набор функций и функций-подобных выражений доступен для создания XML-контента из данных SQL. Таким образом, они особенно подходят для форматирования результатов запросов в XML-документы для обработки в клиентских приложениях.
9.15.1.1. xmlcomment
#
xmlcomment
(text
) →xml
Функция xmlcomment
создает значение XML, содержащее комментарий XML с указанным текстом в качестве содержимого. Текст не может содержать “--
” или заканчиваться на “-
”, иначе полученная конструкция не будет являться допустимым комментарием XML. Если аргумент является пустым, результатом будет также пустое значение.
Пример:
SELECT xmlcomment('hello'); xmlcomment -------------- <!--hello-->
9.15.1.2. xmlconcat
#
xmlconcat
(xml
[, ...] ) →xml
Функция xmlconcat
объединяет список отдельных XML-значений для создания единственного значения, содержащего фрагмент XML-контента. Пустые значения опускаются; результат будет пустым только в случае отсутствия ненулевых аргументов.
Пример:
SELECT xmlconcat('<abc/>', '<bar>foo</bar>'); xmlconcat ---------------------- <abc/><bar>foo</bar>
Если присутствуют XML-объявления, они объединяются следующим образом. Если все значения аргументов имеют одно и то же объявление версии XML, то эта версия используется в результате, иначе версия не используется. Если все значения аргументов имеют значение объявления автономности "yes", то это значение используется в результате. Если все значения аргументов имеют значение объявления автономности и по крайней мере одно из них "no", то это значение используется в результате. В противном случае результат не будет содержать объявления автономности. Если определено, что результат требует объявления автономности, но нет объявления версии, будет использовано объявление версии 1.0, поскольку XML требует, чтобы XML-объявление содержало объявление версии. Объявления кодировки игнорируются и удаляются во всех случаях.
Пример:
SELECT xmlconcat('<?xml version="1.1"?><foo/>', '<?xml version="1.1" standalone="no"?><bar/>'); xmlconcat ----------------------------------- <?xml version="1.1"?><foo/><bar/>
9.15.1.3. xmlelement
#
xmlelement
(NAME
name
[,XMLATTRIBUTES
(attvalue
[AS
attname
] [, ...] )] [,content
[, ...]] ) →xml
Выражение xmlelement
создает XML-элемент с указанным именем, атрибутами и содержимым.
Показанные в синтаксисе элементы name
и attname
являются простыми идентификаторами, а не значениями. Элементы attvalue
и content
являются выражениями, которые могут
представлять любой тип данных Tantor BE.
Аргумент(ы) внутри XMLATTRIBUTES
генерируют атрибуты
XML-элемента; значения content
объединяются для формирования его содержимого.
Примеры:
SELECT xmlelement(name foo); xmlelement ------------ <foo/> SELECT xmlelement(name foo, xmlattributes('xyz' as bar)); xmlelement ------------------ <foo bar="xyz"/> SELECT xmlelement(name foo, xmlattributes(current_date as bar), 'cont', 'ent'); xmlelement ------------------------------------- <foo bar="2007-01-26">content</foo>
Имена элементов и атрибутов, которые не являются допустимыми именами XML, экранируются путем замены проблемных символов последовательностью _x
, где HHHH
_HHHH
- это шестнадцатеричное представление кодовой точки символа Unicode. Например:
SELECT xmlelement(name "foo$bar", xmlattributes('xyz' as "a&b")); xmlelement ---------------------------------- <foo_x0024_bar a_x0026_b="xyz"/>
Необходимо указывать явное имя атрибута, если значение атрибута является ссылкой на столбец, в таком случае имя столбца будет использоваться по умолчанию в качестве имени атрибута. В остальных случаях атрибуту должно быть явно указано имя. Таким образом, следующий пример является допустимым:
CREATE TABLE test (a xml, b xml); SELECT xmlelement(name test, xmlattributes(a, b)) FROM test;
Но это не так:
SELECT xmlelement(name test, xmlattributes('constant'), a, b) FROM test; SELECT xmlelement(name test, xmlattributes(func(a, b))) FROM test;
Содержимое элемента, если указано, будет отформатировано в соответствии с его типом данных. Если содержимое само по себе имеет тип xml
, можно создавать сложные XML-документы. Например:
SELECT xmlelement(name foo, xmlattributes('xyz' as bar), xmlelement(name abc), xmlcomment('test'), xmlelement(name xyz)); xmlelement ---------------------------------------------- <foo bar="xyz"><abc/><!--test--><xyz/></foo>
Содержимое других типов будет отформатировано в допустимые данные XML. Это означает, что символы <, > и & будут преобразованы в сущности. Двоичные данные (тип данных bytea
) будут представлены в кодировке base64 или hex, в зависимости от значения параметра конфигурации xmlbinary. Ожидается, что конкретное поведение для отдельных типов данных будет развиваться, чтобы согласовать отображения PostgreSQL с теми, которые указаны в стандарте SQL:2006 и более поздних версиях, как описано в разделе Раздел D.3.1.3.
9.15.1.4. xmlforest
#
xmlforest
(content
[AS
name
] [, ...] ) →xml
Выражение xmlforest
создает XML-лес (последовательность) элементов с использованием указанных имен и содержимого. Что касается xmlelement
, каждое name
должно быть простым идентификатором, в то время как выражения content
могут иметь любой тип данных.
Примеры:
SELECT xmlforest('abc' AS foo, 123 AS bar); xmlforest ------------------------------ <foo>abc</foo><bar>123</bar> SELECT xmlforest(table_name, column_name) FROM information_schema.columns WHERE table_schema = 'pg_catalog'; xmlforest ----------------------------------------------------------------------- <table_name>pg_authid</table_name><column_name>rolname</column_name> <table_name>pg_authid</table_name><column_name>rolsuper</column_name> ...
Как видно из второго примера, имя элемента можно опустить, если значение содержимого является ссылкой на столбец, в этом случае по умолчанию используется имя столбца. В противном случае, необходимо указать имя.
Имена элементов, которые не являются допустимыми именами XML, экранируются, как показано
для xmlelement
выше. Аналогично, содержимое
данных экранируется для создания допустимого XML-содержимого, если оно не является
типом xml
.
Обратите внимание, что леса XML не являются допустимыми XML-документами, если они состоят
из более чем одного элемента, поэтому может быть полезно обернуть
выражения xmlforest
в
xmlelement
.
9.15.1.5. xmlpi
#
xmlpi
(NAME
name
[,content
] ) →xml
Выражение xmlpi
создает инструкцию обработки XML.
Что касается xmlelement
,
name
должно быть простым идентификатором, а
выражение content
может иметь любой тип данных.
content
, если присутствует, не должно содержать
последовательность символов ?>
.
Пример:
SELECT xmlpi(name php, 'echo "hello world";'); xmlpi ----------------------------- <?php echo "hello world";?>
9.15.1.6. xmlroot
#
xmlroot
(xml
,VERSION
{text
|NO VALUE
} [,STANDALONE
{YES
|NO
|NO VALUE
} ] ) →xml
Выражение xmlroot
изменяет свойства корневого узла значения XML. Если указана версия, она заменяет значение в объявлении версии корневого узла; если указано значение для автономного режима, оно заменяет значение в объявлении автономного режима корневого узла.
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>
9.15.1.7. xmlagg
#
xmlagg
(xml
) →xml
Функция xmlagg
является, в отличие от других
функций, описанных здесь, агрегатной функцией. Она объединяет
входные значения в вызове агрегатной функции,
подобно тому, как это делает xmlconcat
, за исключением того, что объединение
происходит между строками, а не между выражениями в одной строке.
См. Раздел 9.21 для дополнительной информации
об агрегатных функциях.
Пример:
CREATE TABLE test (y int, x xml); INSERT INTO test VALUES (1, '<foo>abc</foo>'); INSERT INTO test VALUES (2, '<bar/>'); SELECT xmlagg(x) FROM test; xmlagg ---------------------- <foo>abc</foo><bar/>
Для определения порядка конкатенации можно добавить к вызову агрегатной функции
предложение ORDER BY
, как описано в разделе
Раздел 4.2.7. Например:
SELECT xmlagg(x ORDER BY y DESC) FROM test; xmlagg ---------------------- <bar/><foo>abc</foo>
Следующий нестандартный подход ранее рекомендовался, и может быть по-прежнему полезен в определенных случаях:
SELECT xmlagg(x) FROM (SELECT * FROM test ORDER BY y DESC) AS tab; xmlagg ---------------------- <bar/><foo>abc</foo>
9.15.2. Предикаты XML #
Выражения, описанные в этом разделе, проверяют свойства значений типа xml
.
9.15.2.1. IS DOCUMENT
#
xml
IS DOCUMENT
→boolean
Выражение IS DOCUMENT
возвращает true, если аргумент XML-значение является правильным XML-документом, false, если это не так (то есть, это фрагмент содержимого), или null, если аргумент равен null. См. Раздел 8.13 разницу между документами и фрагментами содержимого.
9.15.2.2. IS NOT DOCUMENT
#
xml
IS NOT DOCUMENT
→boolean
Выражение IS NOT DOCUMENT
возвращает значение false, если аргумент XML является правильным XML-документом, true, если он не является (то есть, это фрагмент содержимого), или null, если аргумент является null.
9.15.2.3. XMLEXISTS
#
XMLEXISTS
(text
PASSING
[BY
{REF
|VALUE
}]xml
[BY
{REF
|VALUE
}] ) →boolean
Функция xmlexists
выполняет вычисление выражения XPath 1.0 (первый аргумент) с переданным значением XML в качестве контекстного элемента. Функция возвращает false, если результат этой оценки дает пустой набор узлов, и true, если он дает любое другое значение. Функция возвращает null, если любой из аргументов равен null. Ненулевое значение, переданное в качестве контекстного элемента, должно быть XML-документом, а не фрагментом содержимого или любым другим не-XML значением.
Пример:
SELECT xmlexists('//town[text() = ''Toronto'']' PASSING BY VALUE '<towns><town>Toronto</town><town>Ottawa</town></towns>'); xmlexists ------------ t (1 row)
Предложения BY REF
и BY VALUE
принимаются в Tantor BE, но игнорируются, как обсуждалось в Раздел D.3.2.
В стандарте SQL функция xmlexists
выполняет выражение на языке запросов XML,
но Tantor BE позволяет только выражение XPath 1.0,
как описано в
Раздел D.3.1.
9.15.2.4. xml_is_well_formed
#
xml_is_well_formed
(text
) →boolean
xml_is_well_formed_document
(text
) →boolean
xml_is_well_formed_content
(text
) →boolean
Эти функции проверяют, является ли строка типа text
корректным XML и возвращают логический результат. Функция xml_is_well_formed_document
проверяет корректность документа, а функция xml_is_well_formed_content
проверяет корректность содержимого. Функция xml_is_well_formed
выполняет первое, если параметр конфигурации xmloption установлен в DOCUMENT
, или второе, если он установлен в CONTENT
. Это означает, что функция xml_is_well_formed
полезна для проверки успешности простого приведения к типу xml
, в то время как другие две функции полезны для проверки успешности соответствующих вариантов XMLPARSE
.
Примеры:
SET xmloption TO DOCUMENT; SELECT xml_is_well_formed('<>'); xml_is_well_formed -------------------- f (1 row) SELECT xml_is_well_formed('<abc/>'); xml_is_well_formed -------------------- t (1 row) SET xmloption TO CONTENT; SELECT xml_is_well_formed('abc'); xml_is_well_formed -------------------- t (1 row) SELECT xml_is_well_formed_document('<pg:foo xmlns:pg="http://postgresql.org/stuff">bar</pg:foo>'); xml_is_well_formed_document ----------------------------- t (1 row) SELECT xml_is_well_formed_document('<pg:foo xmlns:pg="http://postgresql.org/stuff">bar</my:foo>'); xml_is_well_formed_document ----------------------------- f (1 row)
Последний пример показывает, что проверки включают в себя сопоставление пространств имен.
9.15.3. Обработка XML #
Для обработки значений типа xml
PostgreSQL предлагает функции xpath
и xpath_exists
, которые вычисляют выражения XPath 1.0, а также табличную функцию XMLTABLE
.
9.15.3.1. xpath
#
xpath
(xpath
text
,xml
xml
[,nsarray
text[]
] ) →xml[]
Функция xpath
выполняет выражение XPath 1.0
xpath
(представленное в виде текста)
против значения XML
xml
. Возвращает массив значений XML,
соответствующих набору узлов, созданному выражением XPath.
Если выражение XPath возвращает скалярное значение, а не набор узлов,
возвращается массив с одним элементом.
Второй аргумент должен быть правильно сформированным XML-документом. В частности, он должен иметь единственный корневой элемент узла.
Необязательный третий аргумент функции - это массив пространств имен. Этот массив должен быть двумерным массивом типа text
с длиной второй оси, равной 2 (то есть это должен быть массив массивов, каждый из которых состоит ровно из 2 элементов). Первый элемент каждой записи массива - это имя пространства имен (псевдоним), второй - URI пространства имен. Не требуется, чтобы псевдонимы, указанные в этом массиве, совпадали с теми, которые используются в самом XML-документе (другими словами, как в XML-документе, так и в контексте функции xpath, псевдонимы являются локальными).
Пример:
SELECT xpath('/my:a/text()', '<my:a xmlns:my="http://example.com">test</my:a>', ARRAY[ARRAY['my', 'http://example.com']]); xpath -------- {test} (1 row)
Для работы с пространствами имен по умолчанию (анонимными) можно сделать следующее:
SELECT xpath('//mydefns:b/text()', '<a xmlns="http://example.com"><b>test</b></a>', ARRAY[ARRAY['mydefns', 'http://example.com']]); xpath -------- {test} (1 row)
9.15.3.2. xpath_exists
#
xpath_exists
(xpath
text
,xml
xml
[,nsarray
text[]
] ) →boolean
Функция xpath_exists
является специализированной формой функции xpath
. Вместо возвращения отдельных XML-значений, удовлетворяющих выражению XPath 1.0, эта функция возвращает логическое значение, указывающее, был ли выполнен запрос или нет (то есть, было ли получено какое-либо значение, отличное от пустого набора узлов). Эта функция эквивалентна предикату XMLEXISTS
, за исключением того, что она также поддерживает аргумент сопоставления пространства имен.
Пример:
SELECT xpath_exists('/my:a/text()', '<my:a xmlns:my="http://example.com">test</my:a>', ARRAY[ARRAY['my', 'http://example.com']]); xpath_exists -------------- t (1 row)
9.15.3.3. xmltable
#
XMLTABLE
( [XMLNAMESPACES
(namespace_uri
AS
namespace_name
[, ...] ),]row_expression
PASSING
[BY
{REF
|VALUE
}]document_expression
[BY
{REF
|VALUE
}]COLUMNS
name
{type
[PATH
column_expression
] [DEFAULT
default_expression
] [NOT NULL
|NULL
] |FOR ORDINALITY
} [, ...] ) →setof record
Выражение xmltable
создает таблицу на основе значения XML, фильтра XPath для извлечения строк и набора определений столбцов.
Хотя синтаксически оно напоминает функцию, оно может появляться только в виде таблицы в предложении FROM
запроса.
Необязательное предложение XMLNAMESPACES
предоставляет список определений пространств имен, разделенных запятыми, где каждый namespace_uri
является выражением типа text
, а каждый namespace_name
- простым идентификатором. Она определяет XML-пространства имен, используемые в документе, и их псевдонимы. Спецификация пространства имен по умолчанию в настоящее время не поддерживается.
Требуемый аргумент row_expression
является выражением XPath 1.0 (представленным в виде text
), которое вычисляется, передавая XML-значение document_expression
в качестве контекстного элемента, для получения набора узлов XML. Эти узлы преобразуются в выходные строки xmltable
. Если document_expression
равно null или если row_expression
возвращает пустой набор узлов или любое значение, отличное от набора узлов, то не будет сгенерировано ни одной строки.
document_expression
предоставляет контекстный элемент для row_expression
. Он должен быть правильно сформированным XML-документом; фрагменты/леса не принимаются. предложения BY REF
и BY VALUE
принимаются, но игнорируются, как описано в Раздел D.3.2.
В стандарте SQL функция xmltable
выполняет выражения на языке запросов XML, но Tantor BE позволяет использовать только выражения XPath 1.0, как описано в разделе Раздел D.3.1.
Требуется указать предложение COLUMNS
, которая определяет
столбцы, которые будут созданы в выходной таблице.
См. сводку синтаксиса выше для формата.
Для каждого столбца требуется указать имя и тип данных
(если не указана предложение FOR ORDINALITY
, в этом случае
тип integer
подразумевается неявно). предложения пути, значения по умолчанию и
возможности отсутствуют.
Столбец, помеченный FOR ORDINALITY
, будет заполнен
номерами строк, начиная с 1, в порядке извлечения узлов из
результирующего набора узлов row_expression
.
Только один столбец может быть помечен как FOR ORDINALITY
.
Примечание
XPath 1.0 не указывает порядок узлов в наборе узлов, поэтому код, который полагается на определенный порядок результатов, будет зависеть от реализации. Подробности можно найти в Раздел D.3.1.2.
Значение column_expression
для столбца представляет собой выражение XPath 1.0, которое вычисляется для каждой строки с текущим узлом из результата row_expression
в качестве контекстного элемента, чтобы найти значение столбца. Если не указано выражение column_expression
, то имя столбца используется в качестве неявного пути.
Если выражение XPath столбца возвращает значение, не являющееся XML (что ограничено строкой, логическим или числом в XPath 1.0), и столбец имеет тип PostgreSQL, отличный от xml
, столбец будет установлен так, как если бы значение было присвоено строковому представлению типа PostgreSQL. (Если значение является логическим, его строковое представление считается 1
или 0
, если категория типа выходного столбца является числовой, в противном случае true
или false
).
Если выражение XPath столбца возвращает непустой набор узлов XML, и тип столбца PostgreSQL - xml
, столбцу будет назначен точный результат выражения, если он имеет форму документа или содержимого.
[8]
Результат, не являющийся XML, присвоенный столбцу вывода типа xml
, производит содержимое, один текстовый узел со строковым значением результата.
Если XML-результат присваивается столбцу любого другого типа, то он не может иметь более одного узла, иначе возникает ошибка. Если есть ровно один узел, то столбец будет установлен, как если бы было присвоено строковое значение узла (как определено для функции string
XPath 1.0) для типа PostgreSQL.
Значение строки элемента XML является конкатенацией, в порядке документа, всех текстовых узлов, содержащихся в этом элементе и его наследниках. Значение строки элемента без наследников текстовых узлов является пустой строкой (а не NULL
). Любые атрибуты xsi:nil
игнорируются. Обратите внимание, что узел text()
, содержащий только пробельные символы, между двумя не-текстовыми элементами сохраняется, и что ведущие пробелы в узле text()
не сглаживаются. Для определения значения строки других типов узлов XML и не-XML значений можно обратиться к функции string
XPath 1.0.
Правила преобразования, представленные здесь, не совсем соответствуют стандарту SQL, как обсуждалось в Раздел D.3.1.3.
Если выражение пути возвращает пустой набор узлов (обычно, когда оно не соответствует) для данной строки, то столбец будет установлен в NULL
, если не указано default_expression
; в этом случае будет использовано значение, полученное при вычислении этого выражения.
A default_expression
, вместо того чтобы быть
вычисленным немедленно при вызове xmltable
,
вычисляется каждый раз, когда требуется значение по умолчанию для столбца.
Если выражение является стабильным или постоянным, повторное
вычисление может быть не указано.
Это означает, что вы можете полезно использовать волатильные функции, такие как
nextval
в
default_expression
.
Столбцы могут быть помечены как NOT NULL
. Если column_expression
для столбца NOT NULL
не соответствует ничему, и нет DEFAULT
или default_expression
также вычисляется как null, то будет выдана ошибка.
Примеры:
CREATE TABLE xmldata AS SELECT xml $$ <ROWS> <ROW id="1"> <COUNTRY_ID>AU</COUNTRY_ID> <COUNTRY_NAME>Australia</COUNTRY_NAME> </ROW> <ROW id="5"> <COUNTRY_ID>JP</COUNTRY_ID> <COUNTRY_NAME>Japan</COUNTRY_NAME> <PREMIER_NAME>Shinzo Abe</PREMIER_NAME> <SIZE unit="sq_mi">145935</SIZE> </ROW> <ROW id="6"> <COUNTRY_ID>SG</COUNTRY_ID> <COUNTRY_NAME>Singapore</COUNTRY_NAME> <SIZE unit="sq_km">697</SIZE> </ROW> </ROWS> $$ AS data; SELECT xmltable.* FROM xmldata, XMLTABLE('//ROWS/ROW' PASSING data COLUMNS id int PATH '@id', ordinality FOR ORDINALITY, "COUNTRY_NAME" text, country_id text PATH 'COUNTRY_ID', size_sq_km float PATH 'SIZE[@unit = "sq_km"]', size_other text PATH 'concat(SIZE[@unit!="sq_km"], " ", SIZE[@unit!="sq_km"]/@unit)', premier_name text PATH 'PREMIER_NAME' DEFAULT 'not specified'); id | ordinality | COUNTRY_NAME | country_id | size_sq_km | size_other | premier_name ----+------------+--------------+------------+------------+--------------+--------------- 1 | 1 | Australia | AU | | | not specified 5 | 2 | Japan | JP | | 145935 sq_mi | Shinzo Abe 6 | 3 | Singapore | SG | 697 | | not specified
Следующий пример показывает конкатенацию нескольких узлов text(), использование имени столбца в качестве фильтра XPath и обработку пробелов, XML-комментариев и инструкций обработки:
CREATE TABLE xmlelements AS SELECT xml $$ <root> <element> Hello<!-- xyxxz -->2a2<?aaaaa?> <!--x--> bbb<x>xxx</x>CC </element> </root> $$ AS data; SELECT xmltable.* FROM xmlelements, XMLTABLE('/root' PASSING data COLUMNS element text); element ------------------------- Hello2a2 bbbxxxCC
Следующий пример иллюстрирует, как можно использовать
предложение XMLNAMESPACES
для указания
списка пространств имен, используемых в XML-документе,
а также в выражениях XPath:
WITH xmldata(data) AS (VALUES (' <example xmlns="http://example.com/myns" xmlns:B="http://example.com/b"> <item foo="1" B:bar="2"/> <item foo="3" B:bar="4"/> <item foo="4" B:bar="5"/> </example>'::xml) ) SELECT xmltable.* FROM XMLTABLE(XMLNAMESPACES('http://example.com/myns' AS x, 'http://example.com/b' AS "B"), '/x:example/x:item' PASSING (SELECT data FROM xmldata) COLUMNS foo int PATH '@foo', bar int PATH '@B:bar'); foo | bar -----+----- 1 | 2 3 | 4 4 | 5 (3 rows)
9.15.4. Сопоставление таблиц с XML #
Следующие функции отображают содержимое реляционных таблиц в XML-значения. Их можно рассматривать как функциональность экспорта XML:
table_to_xml
(table
regclass
,nulls
boolean
,tableforest
boolean
,targetns
text
) →xml
query_to_xml
(query
text
,nulls
boolean
,tableforest
boolean
,targetns
text
) →xml
cursor_to_xml
(cursor
refcursor
,count
integer
,nulls
boolean
,tableforest
boolean
,targetns
text
) →xml
table_to_xml
отображает содержимое указанной таблицы, переданной в качестве параметра table
. Тип regclass
принимает строки, идентифицирующие таблицы с использованием обычного синтаксиса, включая опциональную квалификацию схемы и двойные кавычки (см. Раздел 8.19 для получения подробной информации).
query_to_xml
выполняет запрос, текст которого передается в качестве параметра query
, и отображает результат.
cursor_to_xml
извлекает указанное количество строк из курсора, указанного параметром cursor
. Этот вариант рекомендуется, если требуется отобразить большие таблицы, поскольку каждая функция строит результат в памяти.
Если tableforest
равно false, то результирующий
XML-документ будет выглядеть так:
<tablename> <row> <columnname1>data</columnname1> <columnname2>data</columnname2> </row> <row> ... </row> ... </tablename>
Если параметр tableforest
установлен в true, результатом будет фрагмент XML-контента, который выглядит следующим образом:
<tablename> <columnname1>data</columnname1> <columnname2>data</columnname2> </tablename> <tablename> ... </tablename> ...
Если имя таблицы недоступно, то есть при отображении запроса или курсора, в первом формате используется строка table
, а во втором формате - row
.
Выбор между этими форматами остается за пользователем. Первый формат представляет собой правильный XML-документ, что может быть важным во многих приложениях. Второй формат обычно более полезен в функции cursor_to_xml
, если значения результата должны быть впоследствии собраны в один документ. Функции для создания XML-содержимого, обсуждаемые выше, в частности xmlelement
, могут быть использованы для изменения результатов по вкусу.
Данные значения отображаются так же, как описано для функции xmlelement
выше.
Параметр nulls
определяет, должны ли включаться в вывод значения null. Если значение true, то значения null в столбцах представлены как:
<columnname xsi:nil="true"/>
где xsi
- это префикс пространства имен XML для XML
Schema Instance. В результате будет добавлено соответствующее объявление пространства имен.
Если значение false, столбцы, содержащие пустые значения, просто опускаются из вывода.
Параметр targetns
определяет желаемое XML-пространство имен результата. Если не требуется конкретное пространство имен, следует передать пустую строку.
Следующие функции возвращают документы XML Schema, описывающие отображения, выполняемые соответствующими вышеуказанными функциями:
table_to_xmlschema
(table
regclass
,nulls
boolean
,tableforest
boolean
,targetns
text
) →xml
query_to_xmlschema
(query
text
,nulls
boolean
,tableforest
boolean
,targetns
text
) →xml
cursor_to_xmlschema
(cursor
refcursor
,nulls
boolean
,tableforest
boolean
,targetns
text
) →xml
Необходимо передавать одни и те же параметры, чтобы получить соответствующие отображения данных XML и документы XML Schema.
Следующие функции создают отображения данных XML и соответствующую XML-схему в одном документе (или лесу), связанные вместе. Они могут быть полезны, когда требуются автономные результаты и результаты с самоописанием.
table_to_xml_and_xmlschema
(table
regclass
,nulls
boolean
,tableforest
boolean
,targetns
text
) →xml
query_to_xml_and_xmlschema
(query
text
,nulls
boolean
,tableforest
boolean
,targetns
text
) →xml
Кроме того, доступны следующие функции для создания аналогичных отображений всей схемы или всей текущей базы данных:
schema_to_xml
(schema
name
,nulls
boolean
,tableforest
boolean
,targetns
text
) →xml
schema_to_xmlschema
(schema
name
,nulls
boolean
,tableforest
boolean
,targetns
text
) →xml
schema_to_xml_and_xmlschema
(schema
name
,nulls
boolean
,tableforest
boolean
,targetns
text
) →xml
database_to_xml
(nulls
boolean
,tableforest
boolean
,targetns
text
) →xml
database_to_xmlschema
(nulls
boolean
,tableforest
boolean
,targetns
text
) →xml
database_to_xml_and_xmlschema
(nulls
boolean
,tableforest
boolean
,targetns
text
) →xml
Эти функции игнорируют таблицы, которые не доступны для чтения текущим пользователем.
Функции, применяемые к всей базе данных, также игнорируют схемы, для которых текущий пользователь не имеет привилегии USAGE
(поиск).
Обратите внимание, что это потенциально может создать большой объем данных, который нужно будет накапливать в памяти. При запросе сопоставлений содержимого больших схем или баз данных, может быть целесообразно рассмотреть отдельное сопоставление таблиц, возможно, даже через курсор.
Результат сопоставления содержимого схемы выглядит следующим образом:
<schemaname> table1-mapping table2-mapping ... </schemaname>
где формат отображения таблицы зависит от параметра tableforest
, как объяснено выше.
Результат отображения содержимого базы данных выглядит следующим образом:
<dbname> <schema1name> ... </schema1name> <schema2name> ... </schema2name> ... </dbname>
где сопоставление схемы такое, как указано выше.
В качестве примера использования вывода, созданного этими функциями, Пример 9.1 показывает таблицу стилей XSLT, которая преобразует вывод функции table_to_xml_and_xmlschema
в HTML-документ, содержащий табличное представление данных таблицы. Аналогичным образом результаты этих функций могут быть преобразованы в другие форматы на основе XML.
Пример 9.1. XSLT Стиль для преобразования SQL/XML вывода в HTML
<?xml version="1.0"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://www.w3.org/1999/xhtml" > <xsl:output method="xml" doctype-system="http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd" doctype-public="-//W3C/DTD XHTML 1.0 Strict//EN" indent="yes"/> <xsl:template match="/*"> <xsl:variable name="schema" select="//xsd:schema"/> <xsl:variable name="tabletypename" select="$schema/xsd:element[@name=name(current())]/@type"/> <xsl:variable name="rowtypename" select="$schema/xsd:complexType[@name=$tabletypename]/xsd:sequence/xsd:element[@name='row']/@type"/> <html> <head> <title><xsl:value-of select="name(current())"/></title> </head> <body> <table> <tr> <xsl:for-each select="$schema/xsd:complexType[@name=$rowtypename]/xsd:sequence/xsd:element/@name"> <th><xsl:value-of select="."/></th> </xsl:for-each> </tr> <xsl:for-each select="row"> <tr> <xsl:for-each select="*"> <td><xsl:value-of select="."/></td> </xsl:for-each> </tr> </xsl:for-each> </table> </body> </html> </xsl:template> </xsl:stylesheet>
[8]
Результат, содержащий более одного узла верхнего уровня или
нетекстовые пробелы вне элемента, является примером формы содержимого.
Результат XPath может быть ни одной из этих форм, например, если он возвращает
атрибутный узел, выбранный из элемента, который его содержит. Такой результат
будет помещен в форму содержимого, при этом каждый такой недопустимый узел будет заменен
его строковым значением, как определено для функции XPath 1.0
string
.