支持的版本: 当前 (17) / 16 / 15 / 14 / 13
开发版本: devel
不支持的版本: 12 / 11 / 10 / 9.6 / 9.5 / 9.4 / 9.3 / 9.2 / 9.1 / 9.0 / 8.4 / 8.3

F.48. xml2 — XPath 查询和 XSLT 功能 #

xml2 模块提供 XPath 查询和 XSLT 功能。

F.48.1. 弃用通知 #

PostgreSQL 8.3 开始,核心服务器中提供了基于 SQL/XML 标准的 XML 相关功能。该功能涵盖 XML 语法检查和 XPath 查询,这也是此模块的功能,并且功能更多,但 API 完全不兼容。计划在未来的 PostgreSQL 版本中删除此模块,转而使用较新的标准 API,因此我们鼓励您尝试转换您的应用程序。如果您发现此模块的某些功能在新 API 中没有以适当的形式提供,请将您的问题解释给 ,以便可以解决该缺陷。

F.48.2. 函数描述 #

表 F.35 显示了此模块提供的函数。这些函数提供了简单的 XML 解析和 XPath 查询。

表 F.35. xml2 函数

函数

描述

xml_valid ( document text ) → boolean

解析给定的文档,如果文档是格式良好的 XML,则返回 true。(注意:这是标准 PostgreSQL 函数 xml_is_well_formed() 的别名。名称 xml_valid() 在技术上是不正确的,因为有效性和格式良好在 XML 中具有不同的含义。)

xpath_string ( document text, query text ) → text

在提供的文档上评估 XPath 查询,并将结果强制转换为 text

xpath_number ( document text, query text ) → real

在提供的文档上评估 XPath 查询,并将结果强制转换为 real

xpath_bool ( document text, query text ) → boolean

在提供的文档上评估 XPath 查询,并将结果强制转换为 boolean

xpath_nodeset ( document text, query text, toptag text, itemtag text ) → text

在文档上评估查询,并将结果包装在 XML 标签中。如果结果是多值的,则输出将如下所示

<toptag>
<itemtag>Value 1 which could be an XML fragment</itemtag>
<itemtag>Value 2....</itemtag>
</toptag>

如果 toptagitemtag 为空字符串,则省略相关标签。

xpath_nodeset ( document text, query text, itemtag text ) → text

类似于 xpath_nodeset(document, query, toptag, itemtag),但结果省略 toptag

xpath_nodeset ( document text, query text ) → text

类似于 xpath_nodeset(document, query, toptag, itemtag),但结果省略两个标签。

xpath_list ( document text, query text, separator text ) → text

在文档上评估查询,并返回以指定分隔符分隔的多个值,例如,如果 separator,,则返回 值 1,值 2,值 3

xpath_list ( document text, query text ) → text

这是上述函数的包装器,使用 , 作为分隔符。


F.48.3. xpath_table #

xpath_table(text key, text document, text relation, text xpaths, text criteria) returns setof record

xpath_table 是一个表函数,它在一组文档的每个文档上评估一组 XPath 查询,并将结果作为表返回。原始文档表的主键字段作为结果的第一列返回,以便结果集可以很容易地用于连接。参数在 表 F.36 中描述。

表 F.36. xpath_table 参数

参数 描述
key

key 字段的名称 — 这只是一个用作输出表的第一列的字段,即它标识每个输出行来自的记录(请参阅下面关于多个值的说明)

document

包含 XML 文档的字段的名称

relation

包含文档的表或视图的名称

xpaths

一个或多个 XPath 表达式,以 | 分隔

criteria

WHERE 子句的内容。这不能省略,因此如果您想处理关系中的所有行,请使用 true1=1


这些参数(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 输入函数将其转换为整数(或 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.48.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.48.4. XSLT 函数 #

如果安装了 libxslt,则可以使用以下函数

F.48.4.1. xslt_process #

xslt_process(text document, text stylesheet, text paramlist) returns text

此函数将 XSL 样式表应用于文档并返回转换后的结果。 paramlist 是一个参数赋值列表,用于在转换中使用,形式为 a=1,b=2。请注意,参数解析非常简单:参数值不能包含逗号!

还有一个双参数版本的 xslt_process,它不向转换传递任何参数。

F.48.5. 作者 #

John Gray

此模块的开发由 Torchbox Ltd. (www.torchbox.com) 赞助。 它与 PostgreSQL 具有相同的 BSD 许可。

提交更正

如果您发现文档中的任何内容不正确,与您对特定功能的体验不符或需要进一步澄清,请使用此表单报告文档问题。