↑↓ 选择↵ 打开⌫ 切换范围完整搜索

PG.CENTER 连接 PostgreSQL 文档、百科与生态知识。由 Pigsty 维护。

支持中的版本: 当前版本 (18) / 17 / 16 / 15 / 14
开发中的版本: 19 / 20devel
已结束支持的版本: 13 / 12 / 11 / 10 / 9.6 / 9.5 / 9.4 / 9.3 / 9.2 / 9.1 / 9.0 / 8.4 / 8.3

9.15. XML 函数 #

本节中描述的函数以及类函数表达式都作用于类型 xml 的值。关于 xml 类型的详细信息请参见第 8.13 节。用于在值与类型 xml 之间转换的类函数表达式 xmlparse 和 xmlserialize 记录在该节中,而不是本节。

使用大部分这些函数要求 PostgreSQL 使用了 configure --with-libxml 进行编译。

9.15.1. 产生 XML 内容 #

有一组函数和类函数的表达式可以用来从 SQL 数据产生 XML 内容。它们特别适合于将查询结果格式化成 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”,则“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 项是表达式,它们可以产生任意 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 或十六进制编码,具体取决于配置参数 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>
 ...

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

如上文 xmlelement 所示,非法 XML 名字的元素名会被转义。相似地,内容数据也会被转义来产生合法的 XML 内容,除非它已经是一个 xml 类型。

注意如果 XML 森林由多于一个元素组成,那么它不是合法的 XML 文档,因此在 xmlelement 中包装 xmlforest 表达式会有用处。

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

如果参数 XML 值是一个正确的 XML 文档,则 IS DOCUMENT 返回真,如果不是则返回假(即它是一个内容片断),或者是参数为空时返回空。文档和内容片断之间的区别请见第 8.13 节。

9.15.2.2. IS NOT DOCUMENT #

xml IS NOT DOCUMENT → boolean

如果参数中的 XML 值是一个正确的 XML 文档,那么表达式 IS NOT DOCUMENT 返回假,否则返回真(也就是说它是一个内容片段),如果参数为空则返回空。

9.15.2.3. XMLEXISTS #

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

函数 xmlexists 对一个 XPath 1.0 表达式(第一个参数)求值,以传递的 XML 值作为其上下文项。如果求值结果产生一个空节点集,该函数返回 false,如果产生任何其他值,则返回 true。如果任何参数为空,则函数返回 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 子句在 PostgreSQL 中被接受,但会被忽略,如第 D.3.2 节中所述。

在 SQL 标准中,xmlexists 函数对 XML Query 语言的表达式求值,但 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 检查良构的内容。如果 xmloption 配置参数被设置为 DOCUMENT,xml_is_well_formed 会做第一个函数的工作;如果配置参数被设置为 CONTENT,xml_is_well_formed 会做第二个函数的工作。这意味着 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 1.0 表达式的 xpath 和 xpath_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_exists 是 xpath 函数的一种特殊形式。这个函数不是返回满足 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

xmltable 表达式根据给定的 XML 值、用于提取行的 XPath 过滤器和一组列定义生成一个表。虽然它在语法上类似于函数,但它只能作为一个表出现在查询的 FROM 子句中。

可选的 XMLNAMESPACES 子句是一个逗号分隔的名字空间定义列表。其中每个 namespace_uri 是一个 text 表达式,每个 namespace_name 是一个简单的标识符。它指定文档中使用的 XML 名字空间及其别名。当前不支持指定默认名字空间。

必需的 row_expression 参数是一个 XPath 1.0 表达式(以 text 形式给出),对其求值时会将 XML 值 document_expression 作为上下文项,从而得到一组 XML 节点。这些节点就是 xmltable 转换为输出行的内容。如果 document_expression 为空,或者 row_expression 产生空节点集或节点集以外的任何值,则不会产生行。

document_expression 为 row_expression 提供上下文项。它必须是一个良构的 XML 文档;不接受内容片段或森林。BY REF 和 BY VALUE 子句会被接受,但会被忽略,如第 D.3.2 节中所述。

在 SQL 标准中,xmltable 函数对 XML Query 语言中的表达式求值。但 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 中仅限于 string、boolean 或 double),而该列的 PostgreSQL 类型不是 xml,则会按照将该值的字符串表示赋给 PostgreSQL 类型的方式设置该列。(如果值是布尔值,则当输出列的类型类别是数字时,其字符串表示将被视为 1 或 0,否则视为 true 或 false。)

如果一个列的 XPath 表达式返回一个非空的 XML 节点集,并且该列的 PostgreSQL 类型是 xml,那么只要表达式结果是文档或内容形式,就会将该结果原样赋给该列。[8]

赋给 xml 输出列的非 XML 结果会生成内容形式,也就是一个包含结果字符串值的单个文本节点。赋给任何其他类型列的 XML 结果不能包含多个节点,否则会报错。如果恰好只有一个节点,则该列会像把该节点的字符串值(按 XPath 1.0 string 函数的定义)赋给 PostgreSQL 类型一样进行设置。

一个 XML 元素的字符串值,是该元素及其所有后代中包含的文本节点按文档顺序拼接而成的字符串。没有后代文本节点的元素,其字符串值为空字符串(不是 NULL)。所有 xsi:nil 属性都会被忽略。注意,两个非文本元素之间仅含空白的 text() 节点会被保留,text() 节点的前导空白也不会被折叠。其他 XML 节点类型及非 XML 值的字符串值定义规则,可参考 XPath 1.0 的 string 函数。

这里介绍的转换规则并不完全是 SQL 标准中的转换规则,如第 D.3.1.3 节中讨论的那样。

如果路径表达式为给定行返回一个空节点集(通常情况下,当它不匹配时),该列将被设置为 NULL,除非指定了 default_expression;如果指定了该表达式,则使用对它求值所得到的值。

default_expression 并不在调用 xmltable 时立即求值,而是在每次该列需要默认值时才求值。如果表达式是稳定的或不可变的,则可能跳过重复求值。因此,你可以在 default_expression 中使用 nextval 这样的易失性函数。

列可以标记为 NOT NULL。如果某个 NOT NULL 列的 column_expression 没有匹配项,并且未指定 DEFAULT(或者指定的 default_expression 求值结果也为空),就会报错。

示例:

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 中描述的相同方法映射。

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

<columnname xsi:nil="true"/>

其中 xsi 是 XML 模式实例的 XML 名字空间前缀。一个合适的名字空间声明将被加入到结果值中。如果为假,包含空值的列将被从输出中忽略掉。

参数 targetns 指定想要的结果的 XML 名字空间。如果不需要特定的名字空间,应传入一个空字符串。

下面的函数返回 XML 模式文档,这些文档描述上述对应函数所执行的映射:

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 模式文档。

下面的函数产生 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. 转换 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.0string 函数定义的那样。

报告文档问题

阅读 上游文档. 通过 PostgreSQL 文档反馈表单.