Redrock Postgres 搜索 英文
版本: 9.3 / 9.4 / 9.5 / 9.6 / 10 / 11 / 12 / 13 / 14 / 15 / 16 / 17

9.15. XML 函数 #

9.15.1. 生成 XML 内容
9.15.2. XML 谓词
9.15.3. 处理 XML
9.15.4. 将表映射为 XML

本节中所述的函数和类似函数的表达式作用于 xml 类型的数值。关于 xml 类型的信息,请参见 第 8.13 节。对于转换到和转换自 xml 类型的类似函数表达式 xmlparsexmlserialize 在那里记录,不在本节中记录。

要使用这些函数的大部分需要使用 configure --with-libxml 构建 PostgreSQL

9.15.1. 生成 XML 内容 #

提供了一组函数和类似函数表达式,用于根据 SQL 数据生成 XML 内容。这样,它们特别适用于将查询结果格式化为 XML 文档以在客户端应用程序中进行处理。

9.15.1.1. xmltext #

xmltext ( text ) → xml

函数 xmltext 返回一个 XML 值,其中包含一个文本节点,该节点包含用作其内容的输入参数。预定义的实体(例如,和号 (&)、左尖括号和右尖括号 (< >) 以及引号 (""))已转义。

举例

SELECT xmltext('< foo & bar >');
         xmltext
-------------------------
 &lt; foo &amp; bar &gt;

9.15.1.2. xmlcomment #

xmlcomment ( text ) → xml

函数 xmlcomment 创建一个 XML 值,其中包含一个 XML 注释,该注释包含指定的文本作为其内容。该文本不能包含 -- 或以 - 结尾,否则,所得结构将不是有效的 XML 注释。如果参数为 null,则结果为 null。

举例

SELECT xmlcomment('hello');

  xmlcomment
--------------
 <!--hello-->

9.15.1.3. xmlconcat #

xmlconcat ( xml [, ...] ) → xml

函数 xmlconcat 连接多个 XML 值以创建一个值,其中包含 XML 内容片段。Null 值将被忽略;只有在没有非 null 参数时,结果才为 null。

举例

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.4. xmlelement #

xmlelement ( NAME name [, XMLATTRIBUTES ( attvalue [ AS attname ] [, ...] ) ] [, content [, ...]] ) → xml

xmlelement 表达式生成一个带有指定名称、属性和内容的 XML 元素。nameattname 是简单的标识符,而不是值。 attvaluecontent 是可以生成任何 PostgreSQL 数据类型的表达式。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 名称的元素和属性名称通过将违规字符替换为序列 _xHHHH_ 转义掉,其中 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.5. xmlforest #

xmlforest ( content [ AS name ] [, ...] ) → xml

xmlforest 表达式使用给定的名称和内容生成一个元素的 XML forest(序列)。与 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>
 ...

如第二个示例中所示,如果内容值是列引用,则可以省略元素名称,在这种情况下,默认使用列名称。否则,必须指定名称。

类似上面 xmlelement 的情况,无效 XML 名称的元素名称按所示方式进行转义。类似地,会对内容数据进行转义以使其成为有效 XML 内容,除非它已经是 xml 类型。

请注意,如果 XML 林包含多个元素,则它们不是有效的 XML 文档,因此将 xmlforest 表达式包装在 xmlelement 中可能会有用。

9.15.1.6. 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.7. xmlroot #

xmlroot ( xml, VERSION {text|NO VALUE} [, STANDALONE {YES|NO|NO VALUE} ] ) → xml

xmlroot 表达式会更改 XML 值的根节点的属性。如果指定了版本,则会替换根节点的版本声明中的值;如果指定了 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>

9.15.1.8. 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 DOCUMENTboolean

如果参数 XML 值是正确的 XML 文档,则 IS DOCUMENT 表达式返回 true,如果不是(即它是内容片段),则返回 false,如果参数为 null,则返回 null。有关文档和内容片段之间的差异,请参见 第 8.13 节

9.15.2.2. IS NOT DOCUMENT #

xml IS NOT DOCUMENTboolean

表达式 IS NOT DOCUMENT 对于 XML 值作为正确 XML 文档时会返回 false,为 false 时(即内容片断时)会返回 true,对于自变量返回为 null 时会返回 null。

9.15.2.3. XMLEXISTS #

XMLEXISTS ( text PASSING [BY {REF|VALUE}] xml [BY {REF|VALUE}] ) → boolean

函数 xmlexists 使用经过 XML 值作为其上下文项的 XPath 1.0 表达式(第一个自变量)进行计算。对于节点集计算结果为空,函数返回 false;对于返回其他任意值,函数返回 true。对于自变量返回为 null,函数返回 null。任何返回为非 null 的值,均必须作为上下文项以 XML 文档为准,不能设置为内容片断或其他非 XML 值。

举例

SELECT xmlexists('//town[text() = ''Toronto'']' PASSING BY VALUE '<towns><town>Toronto</town><town>Ottawa</town></towns>');

 xmlexists
------------
 t
(1 row)

PostgreSQL 中,BY REF 以及 BY VALUE 子句会被接受,但是会遭到忽略,如在 第 D.3.2 节 中讨论的那样。

在 SQL 标准中,xmlexists 功能在 XML 查询语言中计算表达,不过 PostgreSQL 只允许 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="https://postgresql.ac.cn/stuff">bar</pg:foo>');
 xml_is_well_formed_document
-----------------------------
 t
(1 row)

SELECT xml_is_well_formed_document('<pg:foo xmlns:pg="https://postgresql.ac.cn/stuff">bar</my:foo>');
 xml_is_well_formed_document
-----------------------------
 f
(1 row)

最后一个示例说明了检查结果包含是否正确匹配名称空间。

9.15.3. 处理 XML #

要处理数据类型为 xml 的值,PostgreSQL 提供以下函数:评估 XPath 1.0 表达式的 xpathxpath_exists,以及 XMLTABLE 表函数。

9.15.3.1. xpath #

xpath ( xpath text, xml xml [, nsarray text[] ] ) → xml[]

函数 xpath 使用 XML 值 xml 来评估 XPath 1.0 表达式 xpath(文本形式)。它会返回一个 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_existsxpath 函数的一种特殊形式。此函数不会返回满足 XPath 1.0 表达式的各个 XML 值,而只会返回指示查询是否得到满足的布尔值(具体来说,它会指示是否生成了除空节点集之外的其他值)。此函数等效于 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

基于 XML 值、XPath 筛选器(用于提取行)和一组列定义,xmltable 表达式生成一个表。尽管它的语法类似于函数,但它只能作为查询 FROM 子句中的一个表出现。

可选的 XMLNAMESPACES 子句提供了一个由命名空间定义组成的逗号分隔列表,其中各个 namespace_uritext 表达式,并且各个 namespace_name 为简单标识符。它指定了文档中使用的 XML 命名空间及其别名。目前不提供对默认命名空间规范的支持。

必需的 row_expression 参数是一个 XPath 1.0 表达式(以 text 提供),它会通过传递 XML 值 document_expression 作为其上下文项来评估,以获取一组 XML 节点。这些节点是 xmltable 转换为输出行的内容。如果 document_expression 为空,或者如果 row_expression 产生一个空节点集或节点集以外的任何值,则不会产生任何行。

document_expressionrow_expression 提供上下文项。它必须是一个格式完善的 XML 文档;不接受片段/forest。如 D.3.2 节 中所述,接受 BY REFBY VALUE 子句,但忽略它们。

在 SQL 标准中,xmltable 函数在 XML 查询语言中评估表达式,但 PostgreSQL 仅允许 XPath 1.0 表达式,如 D.3.1 节 中所述。

必需的 COLUMNS 子句指定将在输出表中产生的列。有关格式,请参见上面的语法摘要。每列都需要一个名称,数据类型也是如此(除非指定了 FOR ORDINALITY,在这种情况下隐式指定类型 integer)。路径、缺省值和可空性子句是可选的。

标记为 FOR ORDINALITY 的列会填充行号,从小于 row_expression 的结果节点集获取的节点的顺序开始,从 1 开始。至多一列可标记为 FOR ORDINALITY

注意

XPath 1.0 并未对节点集中的节点指定顺序,因此依赖于结果的特定顺序的代码与实现相关。可在 D.3.1.2 节 中找到详细信息。

column_expression 是一组 XPath 1.0 表达式,在每一行进行求值,以 row_expression 结果中的当前节点作为上下文项,从而找出该列的值。如果没有给出 column_expression,那么列名称将作为隐式路径使用。

如果一列的 XPath 表达式返回一个非 XML 值(在 XPath 1.0 中限定为字符串、布尔值或双精度),并且该列具有除 xml 以外的 PostgreSQL 类型,那么将根据将该值的字符串表示形式分配至 PostgreSQL 类型来设置该列。(如果该值是布尔值,如果输出列的类型类别是数字,那么就将字符串表示形式视为 10,否则视为 truefalse。)

如果一列的 XPath 表达式返回一组非空的 XML 节点,并且该列的 PostgreSQL 类型是 xml,那么如果它是文档或内容形式的,将准确地将该表达式的结果分配至该列。[8]

分配给 xml 输出列的非 XML 结果产生内容,一个字符串值为结果的单文本节点。分配给任何其他类型的列的 XML 结果不可能有多个节点,否则会引发错误。如果恰好有一个节点,将根据将节点的字符串值(如针对 XPath 1.0 string 函数定义的那样)分配至 PostgreSQL 类型的做法来设置该列。

XML 元素的字符串值是在文档顺序中连接该元素以及其后代中包含的所有文本节点所得。没有后代文本节点的元素的字符串值是一个空字符串(不是 NULL)。忽略任何 xsi:nil 属性。请注意,两个非文本元素之间仅包含空格的 text() 节点会保留,并且 text() 节点上的前导空格不会被压扁。可以查阅 XPath 1.0 string 函数来获取定义其他 XML 节点类型和非 XML 值的字符串值的规则。

此处显示的转换规则并非 SQL 标准,如此处所述:第 D.3.1.3 节

如果路径表达式对于给定行返回一个空的节点集(通常在不匹配时),除非指定了 default_expression,否则列将被设置为 NULL;然后使用由此表达式计算得到的值。

在调用 xmltabledefault_expression 不会立即被计算,而是在需要为列提供默认值时才进行计算。如果表达式有资格被认为是稳定的或不可变的,则可以跳过重复计算。这意味着,您可以在 default_expression 中有效地使用像 nextval 这样的易失性函数。

列可以标记为 NOT NULL。如果 NOT NULL 列的 column_expression 与任何内容都不匹配,并且没有 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 为假,则结果 XML 文档看起来像这样

<tablename>
  <row>
    <columnname1>data</columnname1>
    <columnname2>data</columnname2>
  </row>

  <row>
    ...
  </row>

  ...
</tablename>

如果 tableforest 为真,则结果是看起来像这样的 XML 内容片段

<tablename>
  <columnname1>data</columnname1>
  <columnname2>data</columnname2>
</tablename>

<tablename>
  ...
</tablename>

...

如果表格名不可用,即,在映射查询或光标时,则在第一种格式中使用字符串 table,在第二种格式中使用 row

用户需要在这些格式之间做出选择。第一个格式是一个合适的 XML 文档,该格式在许多应用程序中非常重要。第二个格式往往在 cursor_to_xml 函数中更有用,如果后续需要将结果值重新组装到一个文档中。上面讨论的用于生成 XML 内容的函数,特别是 xmlelement,可以用来根据需要修改结果。

数据值映射方式与前面为函数 xmlelement 描述的方式相同。

参数 空值 决定是否应在输出中包含空值。如果为真,则列中的空值表示为

<columnname xsi:nil="true"/>

其中 xsi 是用于 XML Schema 实例的 XML 命名空间前缀。将向结果值添加一个合适的命名空间声明。如果为假,则不包含空值的列将从输出中忽略。

参数 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 Schema,并将其链接在一起。它们可用于需要自包含且自我描述的结果的地方

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. 用于将 SQL/XML 输出转换为 HTML 的 XSLT 样式表

<?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 函数所定义。