F.50. xml2 — XPath 查询和 XSLT 功能#
xml2
模块提供 XPath 查询和 XSLT 功能。
F.50.1. 弃用通知#
从PostgreSQL8.3 开始,核心服务器中基于 SQL/XML 标准的 XML 相关功能。该功能涵盖 XML 语法检查和 XPath 查询,这也是此模块的功能,但 API 完全不兼容。计划在未来版本的 PostgreSQL 中删除此模块,转而使用较新的标准 API,因此建议尝试转换您的应用程序。如果您发现此模块的某些功能在较新的 API 中没有以适当的形式提供,请向<[[email protected]](/cdn-cgi/l/email-protection#f8889f8b8994d590999b939d8a8bb894918b8c8bd688978b8c9f8a9d8b8994d6978a9f)>
解释您的问题,以便解决缺陷。
F.50.2. 函数描述#
表 F.36显示此模块提供的函数。这些函数提供简单的 XML 解析和 XPath 查询。
表 F.36.xml2
函数
函数 描述 |
---|
解析给定的文档,如果文档是格式良好的 XML,则返回 true。(注意:这是标准 PostgreSQL 函数 |
对提供的文档求值 XPath 查询,并将结果强制转换为 |
对提供的文档求值 XPath 查询,并将结果强制转换为 |
对提供的文档求值 XPath 查询,并将结果强制转换为 |
在文档上评估查询并将结果包装在 XML 标记中。如果结果为多值,输出将如下所示 <toptag> <itemtag>Value 1 which could be an XML fragment</itemtag> <itemtag>Value 2....</itemtag> </toptag> 如果 |
类似于 |
类似于 |
在文档上评估查询并返回由指定分隔符分隔的多个值,例如,如果 |
这是上述函数的包装器,使用 |
F.50.3.xpath_table
#
xpath_table(text key, text document, text relation, text xpaths, text criteria) returns setof record
xpath_table
是一个表函数,它对一组文档中的每组 XPath 查询进行评估,并将结果作为表返回。原始文档表中的主键字段作为结果的第一列返回,以便结果集可以轻松用于联接中。参数在表 F.37中进行描述。
表 F.37.xpath_table
参数
参数 | 描述 |
---|---|
key | “key” 字段的名称 — 这只是一个用作输出表第一列的字段,即,它标识来自每个输出行的记录(请参阅有关多个值的注释) |
document | 包含 XML 文档的字段的名称 |
relation | 包含文档的表或视图的名称 |
xpaths | 一个或多个 XPath 表达式,用 |
条件 | WHERE 子句的内容。此项不可省略,因此如果您想处理关系中的所有行,请使用 |
这些参数(XPath 字符串除外)只会替换为一个普通的 SQL SELECT 语句,因此您有一些灵活性 — 语句是
SELECT <key>, <document> FROM <relation> WHERE <criteria>
因此,这些参数可以在这些特定位置有效地成为任何内容。此 SELECT 的结果需要返回两列(除非您尝试为键或文档列出多个字段)。请注意,这种简单的方法要求您验证任何用户提供的值,以避免 SQL 注入攻击。
该函数必须在FROM
表达式中使用,并使用AS
子句指定输出列;例如
SELECT * FROM
xpath_table('article_id',
'article_xml',
'articles',
'/article/author|/article/pages|/article/title',
'date_entered > ''2003-01-01'' ')
AS t(article_id integer, author text, page_count integer, title text);
AS
子句定义输出表中列的名称和类型。第一个是“键”字段,其余对应于 XPath 查询。如果 XPath 查询多于结果列,则会忽略额外的查询。如果结果列多于 XPath 查询,则额外的列将为 NULL。
请注意,此示例将page_count
结果列定义为一个整数。该函数在内部处理字符串表示形式,因此当您说您想要输出中的一个整数时,它将获取 XPath 结果的字符串表示形式并使用 PostgreSQL 输入函数将其转换为一个整数(或AS
子句请求的任何类型)。如果无法执行此操作,则会导致错误 — 例如,如果结果为空 — 因此,如果您认为您的数据有任何问题,您可能希望仅坚持使用text
作为列类型。
调用SELECT
语句不一定要只是SELECT *
— 它可以通过名称引用输出列或将其连接到其他表。该函数生成一个虚拟表,您可以使用它执行任何您希望的操作(例如,聚合、连接、排序等)。因此,我们还可以有
SELECT t.title, p.fullname, p.email
FROM xpath_table('article_id', 'article_xml', 'articles',
'/article/title|/article/author/@id',
'xpath_string(article_xml,''/article/@date'') > ''2003-03-20'' ')
AS t(article_id integer, title text, author_id integer),
tblPeopleInfo AS p
WHERE t.author_id = p.person_id;
作为一个更复杂的示例。当然,您可以出于方便起见将所有这些包装在视图中。
F.50.3.1. 多值结果#
xpath_table
函数假设每个 XPath 查询的结果可能是多值的,因此函数返回的行数可能与输入文档数不同。返回的第一行包含每个查询的第一个结果,第二行包含每个查询的第二个结果。如果其中一个查询的值少于其他查询,则将返回空值。
在某些情况下,用户会知道给定的 XPath 查询只会返回一个结果(可能是唯一的文档标识符)——如果与返回多个结果的 XPath 查询一起使用,则单值结果只会出现在结果的第一行。解决方法是将键字段用作与更简单的 XPath 查询进行联接的一部分。例如
CREATE TABLE test (
id int PRIMARY KEY,
xml text
);
INSERT INTO test VALUES (1, '<doc num="C1">
<line num="L1"><a>1</a><b>2</b><c>3</c></line>
<line num="L2"><a>11</a><b>22</b><c>33</c></line>
</doc>');
INSERT INTO test VALUES (2, '<doc num="C2">
<line num="L1"><a>111</a><b>222</b><c>333</c></line>
<line num="L2"><a>111</a><b>222</b><c>333</c></line>
</doc>');
SELECT * FROM
xpath_table('id','xml','test',
'/doc/@num|/doc/line/@num|/doc/line/a|/doc/line/b|/doc/line/c',
'true')
AS t(id int, doc_num varchar(10), line_num varchar(10), val1 int, val2 int, val3 int)
WHERE id = 1 ORDER BY doc_num, line_num
id | doc_num | line_num | val1 | val2 | val3
----+---------+----------+------+------+------
1 | C1 | L1 | 1 | 2 | 3
1 | | L2 | 11 | 22 | 33
要在每一行获取doc_num
,解决方案是使用xpath_table
的两个调用并联接结果
SELECT t.*,i.doc_num FROM
xpath_table('id', 'xml', 'test',
'/doc/line/@num|/doc/line/a|/doc/line/b|/doc/line/c',
'true')
AS t(id int, line_num varchar(10), val1 int, val2 int, val3 int),
xpath_table('id', 'xml', 'test', '/doc/@num', 'true')
AS i(id int, doc_num varchar(10))
WHERE i.id=t.id AND i.id=1
ORDER BY doc_num, line_num;
id | line_num | val1 | val2 | val3 | doc_num
----+----------+------+------+------+---------
1 | L1 | 1 | 2 | 3 | C1
1 | L2 | 11 | 22 | 33 | C1
(2 rows)
F.50.4. XSLT 函数#
如果安装了 libxslt,则可以使用以下函数
F.50.4.1.xslt_process
#
xslt_process(text document, text stylesheet, text paramlist) returns text
此函数将 XSL 样式表应用于文档并返回转换后的结果。paramlist
是要用于转换的参数分配列表,其形式为a=1,b=2
。请注意,参数解析非常简单:参数值不能包含逗号!
还有两参数版本的xslt_process
,它不会将任何参数传递给转换。
F.50.5. 作者#
John Gray<[[email protected]](/cdn-cgi/l/email-protection#94fef3e6f5edd4f5eee1f8fdbaf7fbbae1ff)>
此模块的开发由 Torchbox Ltd.(www.torchbox.com)赞助。它具有与 PostgreSQL 相同的 BSD 许可证。