PostgreSQL 9.3.1 中文手册 | ||||
---|---|---|---|---|
Prev | Up | Appendix F. 额外提供的模块 | Next |
xml2模块提供XPath查询和XSLT功能。
从PostgreSQL 8.3开始,在内核服务器中有一个基于SQL/XML标准的XML相关的功能。
这个功能包含了XML语法检查和XPath查询,这也是这个模块的包含的,甚至更多,不过API一点也不兼容。
计划在未来的PostgreSQL版本中删除这个模块,支持新的标准的API,所以鼓励你尝试转换你的应用。
如果你发现这个模块的某些功能在一个适当形式的更新的API中不可用,
请解释你的问题到<[email protected]>
,以便解决这个缺陷。
Table F-32显示了这个模块提供的函数。 这些函数提供了简单的XMP解析和XPath查询。所有参数都是text类型的, 所以为了简化没有显示。
Table F-32. 函数
函数 | 返回 | 描述 |
---|---|---|
xml_is_well_formed(document)
| bool |
解析它的参数中的文件正文,并且如果文件是格式良好的XML则返回真。
(注意:在PostgreSQL 8.2之前,这个函数称为 |
xpath_string(document, query)
| text |
这个函数在提供的文件上评估XPath查询,并转换结果到指定的类型。 |
xpath_number(document, query)
| float4 | |
xpath_bool(document, query)
| bool | |
xpath_nodeset(document, query, toptag, itemtag)
| text |
在文件上评估查询并将结果包装在XML标签中。如果结果是多值的,那么输出将看起来像: <toptag> <itemtag>Value 1 which could be an XML fragment</itemtag> <itemtag>Value 2....</itemtag> </toptag> 如果toptag或itemtag中的任意一个是空字符串,那么省略相关的标签。 |
xpath_nodeset(document, query)
| text |
类似于 |
xpath_nodeset(document, query, itemtag)
| text |
类似于 |
xpath_list(document, query, separator)
| text |
这个函数返回由指定的分隔符分开的多个值,例如如果分隔符是,, 返回值是Value 1,Value 2,Value 3。 |
xpath_list(document, query)
| text | 这是一个对于使用,作为分隔符的以上函数的包装器。 |
xpath_table(text key, text document, text relation, text xpaths, text criteria) returns setof record
xpath_table
是一个表函数,在每一组文档上计算一组XPath查询,
并作为一个表返回结果。原始文档表的主键字段作为结果的第一个字段返回,
因此结果集可以容易的用于连接。参数在Table F-33中描述。
Table F-33. xpath_table
参数
参数 | 描述 |
---|---|
key |
"key"字段的名字—这只是用作输出表的第一个字段,也就是, 它识别每个传来的输出行的记录(请参见下面关于多行值的注释) |
document |
包含XML文档的字段名 |
relation |
包含文档的表或视图的名字 |
xpaths |
一个或多个XPath表达式,由|分隔 |
criteria |
WHERE子句的内容。这个不能省略,所以如果你想要在关系中处理所有的行, 那么使用true或1=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查询,那么额外的字段将为空。
请注意,这个示例定义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;
作为一个更复杂的示例。当然,为了方便,你可以将所有这些包装到一个视图中。
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)
如果安装了libxslt,那么下列的函数是可用的:
xslt_process(text document, text stylesheet, text paramlist) returns text
这个函数应用XSL样式表到文档并返回转换了的结果。paramlist 是一个在转换中使用的参数分配列表,以格式a=1,b=2指定。 请注意,参数分析是非常简单的:参数值不能包含逗号!
也有一个两参数的xslt_process
版本,不传递任何参数到转换。
John Gray <[email protected]>
这个模块的发展是由Torchbox Ltd. (www.torchbox.com)赞助的。 它和PostgreSQL有一样的BSD许可证。