本节描述的函数和类函数表达式作用于
xml
类型的值。
关于
xml
类型的信息请参见
Section 8.13。
用于与
xml
类型互相转换的类函数表达式
xmlparse
和
xmlserialize
记录在那里,
而非本节中。
这些函数中的大多数要求
PostgreSQL
是用
configure --with-libxml
构建的。
有一组函数和类函数表达式可用于从 SQL 数据产生 XML 内容。 因此, 它们特别适合于把查询结果格式化为 XML 文档, 以便在客户端应用程序中处理。
xmltext #xmltext(text) →xml
函数
xmltext
返回一个 XML
值,
它带有单个文本节点,
并把输入参数作为其内容。
预定义实体,
例如与符号
(&)、
左右尖括号
(< >)
和引号
("")
都会被转义。
示例:
SELECT xmltext('< foo & bar >');
xmltext
-------------------------
< foo & bar >
xmlcomment #xmlcomment(text) →xml
函数
xmlcomment
创建一个 XML
值,
其中包含一个以指定文本为内容的 XML
注释。
文本不能包含
“--”
或以
“-”
结尾,
否则产生的构造将不是一个有效的 XML
注释。
如果参数为空,
则结果为空。
示例:
SELECT xmlcomment('hello');
xmlcomment
--------------
<!--hello-->
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/>
xmlelement #xmlelement(NAMEname[,XMLATTRIBUTES(attvalue[ASattname] [, ...] ) ] [,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
名字的元素和属性名,
会通过把出问题的字符替换为序列
_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 或十六进制编码表示,
取决于配置参数
xmlbinary
的设置。
各种数据类型的具体行为预计会演化,
以使 PostgreSQL
的映射与 SQL:2006
及后续版本中规定的映射对齐,
如
Section D.3.1.3
中所讨论。
xmlforest #xmlforest(content[ASname] [, ...] ) →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
中可能会很有用。
xmlpi #xmlpi(NAMEname[,content] ) →xml
xmlpi
表达式创建一个 XML
处理指令。
与
xmlelement
一样,
name
必须是一个简单标识符,
而
content
表达式可以有任何数据类型。
如果存在,
content
不得包含字符序列
?>。
示例:
SELECT xmlpi(name php, 'echo "hello world";');
xmlpi
-----------------------------
<?php echo "hello world";?>
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>
xmlagg #xmlagg(xml) →xml
与这里描述的其他函数不同,
函数
xmlagg
是一个聚集函数。
它把对聚集函数调用的输入值串接起来,
非常类似于
xmlconcat
所做的,
只是串接发生在多个行之间,
而非单行的多个表达式之间。
有关聚集函数的更多信息请参见
Section 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
子句,
如
Section 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>
本节描述的表达式检查
xml
值的属性。
IS DOCUMENT #xmlIS DOCUMENT→boolean
如果参数 XML
值是一个适当的 XML
文档,
表达式
IS DOCUMENT
返回真,
不是则返回假
(也就是说,
它是一个内容片段),
如果参数为空则返回空。
关于文档与内容片段之间的区别,
请参见
Section 8.13。
IS NOT DOCUMENT #xmlIS NOT DOCUMENT→boolean
如果参数 XML
值是一个适当的 XML
文档,
表达式
IS NOT DOCUMENT
返回假,
不是则返回真
(也就是说,
它是一个内容片段),
如果参数为空则返回空。
XMLEXISTS #XMLEXISTS(textPASSING[BY{REF|VALUE}]xml[BY{REF|VALUE}] ) →boolean
函数
xmlexists
求值一个 XPath 1.0
表达式
(第一个参数),
并以传入的 XML
值作为它的上下文项。
如果那次求值的结果产生一个空节点集,
该函数返回假;
如果产生任何其他值,
则返回真。
如果任何参数为空,
该函数返回空。
作为上下文项传入的非空值必须是一个 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
中会被接受,
但被忽略,
如
Section D.3.2
中所讨论。
在 SQL 标准中,
xmlexists
函数求值一个 XML Query
语言中的表达式,
但
PostgreSQL
只允许一个 XPath 1.0
表达式,
如
Section D.3.1
中所讨论。
xml_is_well_formed #xml_is_well_formed(text) →booleanxml_is_well_formed_document(text) →booleanxml_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
类型的简单转换是否会成功很有用,
而另外两个函数对于查看
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)
最后一个例子表明, 检查包括命名空间是否被正确匹配。
为了处理
xml
数据类型的值,
PostgreSQL 提供了求值 XPath 1.0
表达式的
xpath 和
xpath_exists
函数,
以及
XMLTABLE
表函数。
xpath #xpath(xpathtext,xmlxml[,nsarraytext[]] ) →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)
xpath_exists #xpath_exists(xpathtext,xmlxml[,nsarraytext[]] ) →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)
xmltable #XMLTABLE( [XMLNAMESPACES(namespace_uriASnamespace_name[, ...] ), ]row_expressionPASSING[BY{REF|VALUE}]document_expression[BY{REF|VALUE}]COLUMNSname{type[PATHcolumn_expression] [DEFAULTdefault_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
子句会被接受但被忽略,
如
Section D.3.2
中所讨论。
在 SQL 标准中,
xmltable
函数求值 XML Query
语言中的表达式,
但
PostgreSQL
只允许 XPath 1.0
表达式,
如
Section D.3.1
中所讨论。
必需的
COLUMNS
子句指定将在输出表中产生的列。
格式请参见上文的语法摘要。
每一列都需要一个名字和一个数据类型
(除非指定了
FOR ORDINALITY,
在那种情况下隐含的类型是
integer)。
路径、默认值和可空性子句是可选的。
被标记为
FOR ORDINALITY
的列会被填上行编号,
从 1 开始,
顺序是从
row_expression
的结果节点集中检索节点的顺序。
至多只能有一列被标记为
FOR ORDINALITY。
XPath 1.0 没有为节点集中的节点规定顺序, 因此依赖结果的特定顺序的代码将是取决于实现的。 细节可以在 Section D.3.1.2 中找到。
一列的
column_expression
是一个 XPath 1.0
表达式,
它会对每一行求值,
以
row_expression
结果中的当前节点作为它的上下文项,
来找出该列的值。
如果没有给出
column_expression,
那么列名会被用作一个隐式路径。
如果一列的 XPath
表达式返回一个非 XML
值
(在 XPath 1.0
中它被限定为字符串、
布尔值或双精度值),
并且该列具有一个非
xml
的 PostgreSQL
类型,
那么该列的设置方式就如同把该值的字符串表示赋给该 PostgreSQL
类型。
(如果该值是一个布尔值,
当输出列的类型类别是数字时,
其字符串表示被取为
1 或
0,
否则为
true 或
false。)
如果一列的 XPath
表达式返回一个非空的 XML
节点集,
并且该列的 PostgreSQL
类型是
xml,
那么如果该表达式结果处于文档或内容形式,
该列会被精确地赋值为该表达式结果。
[7]
被赋给一个
xml
输出列的非 XML
结果会产生内容,
即一个带有该结果字符串值的单一文本节点。
被赋给任何其他类型列的 XML
结果不得有多于一个节点,
否则会抛出错误。
如果恰好有一个节点,
该列的设置方式就如同把该节点的字符串值
(按 XPath 1.0 的
string
函数的定义)
赋给该 PostgreSQL
类型。
一个 XML
元素的字符串值是该元素及其后代中包含的全部文本节点按文档顺序的
串接。
一个没有后代文本节点的元素的字符串值是一个空字符串
(而非
NULL)。
任何
xsi:nil
属性都会被忽略。
注意,
两个非文本元素之间只有空白的
text()
节点会被保留,
并且
text()
节点上的前导空白不会被展平。
定义其他 XML
节点类型和非 XML
值的字符串值的规则,
请参见 XPath 1.0 的
string
函数。
这里给出的转换规则与 SQL 标准的规则并不完全相同, 如 Section D.3.1.3 中所讨论。
如果路径表达式对某一行返回一个空节点集
(通常发生在它不匹配的时候),
那么该列会被设置为
NULL,
除非指定了一个
default_expression;
在那种情况下会使用对该表达式求值得到的值。
default_expression
并不会在
xmltable
被调用时立即被求值,
而是在每次需要该列的默认值时被求值。
如果该表达式符合稳定或不可变的条件,
可以跳过重复求值。
这意味着你可以有效地在
default_expression
中使用诸如
nextval
之类的易变函数
(create_if_missing
为真时,
如果索引为负,
新值会被加在数组的开头,
为正时加在末尾)
例子:
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)
以下函数把关系表的内容映射为 XML 值。 它们可以被看作 XML 导出功能:
table_to_xml(tableregclass,nullsboolean,tableforestboolean,targetnstext) →xmlquery_to_xml(querytext,nullsboolean,tableforestboolean,targetnstext) →xmlcursor_to_xml(cursorrefcursor,countinteger,nullsboolean,tableforestboolean,targetnstext) →xml
table_to_xml
映射由参数
table
传入的命名表的内容。
regclass
类型接受使用惯用记法标识表的字符串,
包括可选的模式限定和双引号
(细节请参见
Section 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 Schema
Instance 的 XML
命名空间前缀。
会向结果值中添加一个适当的命名空间声明。
如果为假,
包含空值的列会被简单地从输出中省略。
参数
targetns
规定期望的结果 XML
命名空间。
如果不想要任何特定的命名空间,
应当传入一个空字符串。
以下函数返回 XML Schema 文档, 描述上面相应函数执行的映射:
table_to_xmlschema(tableregclass,nullsboolean,tableforestboolean,targetnstext) →xmlquery_to_xmlschema(querytext,nullsboolean,tableforestboolean,targetnstext) →xmlcursor_to_xmlschema(cursorrefcursor,nullsboolean,tableforestboolean,targetnstext) →xml
要获得相匹配的 XML 数据映射和 XML Schema 文档, 传入相同的参数至关重要。
以下函数把 XML 数据映射和相应的 XML Schema 一起放在一个文档 (或森林)中, 并把它们链接起来。 在希望得到自包含、 自描述的结果时, 它们可能很有用:
table_to_xml_and_xmlschema(tableregclass,nullsboolean,tableforestboolean,targetnstext) →xmlquery_to_xml_and_xmlschema(querytext,nullsboolean,tableforestboolean,targetnstext) →xml
此外, 还有一些函数可用于产生整个模式或整个当前数据库的类似映射:
schema_to_xml(schemaname,nullsboolean,tableforestboolean,targetnstext) →xmlschema_to_xmlschema(schemaname,nullsboolean,tableforestboolean,targetnstext) →xmlschema_to_xml_and_xmlschema(schemaname,nullsboolean,tableforestboolean,targetnstext) →xmldatabase_to_xml(nullsboolean,tableforestboolean,targetnstext) →xmldatabase_to_xmlschema(nullsboolean,tableforestboolean,targetnstext) →xmldatabase_to_xml_and_xmlschema(nullsboolean,tableforestboolean,targetnstext) →xml
这些函数会忽略当前用户不可读的表。
数据库级函数还会忽略当前用户对其没有
USAGE
(查找)
特权的模式。
注意, 这些函数有可能产生大量数据, 这些数据需要在内存中构建。 当请求大型模式或数据库的内容映射时, 值得考虑改为逐个映射表, 甚至可能通过一个游标来进行。
模式内容映射的结果看起来像这样:
<schemaname> table1-mapping table2-mapping ... </schemaname>
其中表映射的格式取决于
tableforest
参数,
如上文所解释。
数据库内容映射的结果看起来像这样:
<dbname> <schema1name> ... </schema1name> <schema2name> ... </schema2name> ... </dbname>
其中模式映射如上文所述。
作为使用这些函数产生的输出的一个例子,
Example 9.1
展示了一个 XSLT
样式表,
它把
table_to_xml_and_xmlschema
的输出转换为一个包含表数据表格化呈现的 HTML
文档。
以类似的方式,
这些函数的结果可以被转换为其他基于 XML
的格式。
Example 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>
[7]
一个在顶层包含多于一个元素节点、
或者在元素之外包含非空白文本的结果,
是内容形式的一个例子。
一个 XPath
结果也可能不属于任何形式,
例如当它返回一个从包含它的元素中选出的属性节点时。
这样的结果会被放入内容形式,
其中每个这样的不允许的节点都会被替换为它的字符串值,
如 XPath 1.0 的
string
函数所定义的那样。