名为 xml2
的模块提供了 XPath 查询和 XSLT 功能。
从 PostgreSQL 8.3 开始,核心服务器中提供了基于 SQL/XML 标准的 XML 相关功能。这些功能涵盖了 XML 语法检查和 XPath 查询,这正是本模块的功能,并且功能更强大,但 API 完全不兼容。计划在未来的 PostgreSQL 版本中移除本模块,转而使用新的标准 API,因此鼓励您尝试转换您的应用程序。如果您发现本模块的某些功能在新 API 中没有得到充分支持,请将您的问题告知 <pgsql-hackers@lists.postgresql.org>
,以便改进这些不足之处。
表 F.37 列出了本模块提供的函数。这些函数提供直接的 XML 解析和 XPath 查询。
表 F.37. xml2
函数
函数 描述 |
---|
解析给定的文档,如果文档是格式正确的 XML,则返回 true。(注意:这是标准 PostgreSQL 函数 |
在提供的文档上评估 XPath 查询,并将结果转换为 |
在提供的文档上评估 XPath 查询,并将结果转换为 |
在提供的文档上评估 XPath 查询,并将结果转换为 |
在文档上评估查询并将结果包装在 XML 标签中。如果结果是多值的,输出将如下所示: <toptag> <itemtag>Value 1 which could be an XML fragment</itemtag> <itemtag>Value 2....</itemtag> </toptag> 如果 |
类似于 |
类似于 |
在文档上评估查询,并返回由指定分隔符分隔的多个值,例如,如果 |
这是上面函数的包装器,它使用 |
xpath_table
#xpath_table(text key, text document, text relation, text xpaths, text criteria) returns setof record
xpath_table
是一个表函数,它对一组文档中的每个文档评估一组 XPath 查询,并将结果作为表返回。原始文档表的主键字段作为结果的第一列返回,以便结果集可以方便地用于连接。参数在 表 F.38 中进行了描述。
表 F.38. xpath_table
参数
参数 | 描述 |
---|---|
key |
“key”字段的名称 — 这只是一个用于输出表第一列的字段,即它标识了每一输出行来自的记录(有关多值的注意事项,请参见下文)。 |
document |
包含 XML 文档的字段名称 |
relation |
包含文档的表或视图的名称 |
xpaths |
一个或多个 XPath 表达式,用 |
criteria |
WHERE 子句的内容。此项不能省略,因此如果您想处理 relation 中的所有行,请使用 |
这些参数(XPath 字符串除外)将被直接替换到纯 SQL SELECT 语句中,因此您具有一定的灵活性 — 语句是:
SELECT <key>, <document> FROM <relation> WHERE <criteria>
因此,这些参数可以是那些特定位置的任何有效内容。此 SELECT 的结果需要返回恰好两列(除非您尝试为 key 或 document 列出多个字段,否则它会返回两列)。请注意,这种简单的方法要求您验证任何用户提供的输入值,以避免 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
子句定义了输出表中列的名称和类型。第一列是“key”字段,其余列对应于 XPath 查询。如果 XPath 查询的数量多于结果列的数量,则多余的查询将被忽略。如果结果列的数量多于 XPath 查询的数量,则多余的列将为 NULL。
请注意,此示例将 page_count
结果列定义为整数。该函数内部处理字符串表示形式,因此当您要求输出为整数时,它将获取 XPath 结果的字符串表示形式,并使用 PostgreSQL 的输入函数将其转换为整数(或 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;
作为一个更复杂的例子。当然,您可以为了方便起见,将所有这些内容包装在一个视图中。
函数 xpath_table
假定每个 XPath 查询的结果可能是多值的,因此该函数返回的行数可能与输入文档的数量不同。返回的第一行包含每个查询的第一个结果,第二行包含每个查询的第二个结果。如果某个查询的值少于其他查询,则将返回 NULL 值。
在某些情况下,用户会知道给定的 XPath 查询只会返回一个结果(可能是唯一的文档标识符)— 如果与返回多个结果的 XPath 查询一起使用,该单值结果将仅出现在结果的第一行。解决方法是使用 key 字段作为连接的一部分,与更简单的 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)
如果安装了 libxslt,将提供以下函数:
xslt_process
#xslt_process(text document, text stylesheet, text paramlist) returns text
此函数将 XSL 样式表应用于文档并返回转换后的结果。paramlist
是要在转换中使用的一组参数赋值,其格式为 a=1,b=2
。请注意,参数解析非常简单:参数值不能包含逗号!
还有一个两参数版本的 xslt_process
,它不向转换传递任何参数。
John Gray <jgray@azuli.co.uk>
本模块的开发由 Torchbox Ltd. (www.torchbox.com) 赞助。它与 PostgreSQL 具有相同的 BSD 许可证。
如果您在文档中发现任何不正确之处、与您在使用特定功能时的经验不符之处或需要进一步澄清之处,请使用 此表单 报告文档问题。