Postgresql 中文操作指南
F.50. xml2 — XPath querying and XSLT functionality #
xml2 模块提供 XPath 查询和 XSLT 功能。
F.50.1. Deprecation Notice #
从 PostgreSQL 8.3 开始,核心服务器中提供了基于 SQL/XML 标准的 XML 相关功能。此功能涵盖了 XML 语法检查和 XPath 查询,这是此模块所执行的操作,但 API 完全不兼容。计划在未来版本的 PostgreSQL 中删除此模块,转而使用较新的标准 API,因此鼓励您尝试转换应用程序。如果您发现此模块的某些功能在较新的 API 中没有提供适当的形式,请向 < link:mailto:pgsql-hackers@lists.postgresql.org[pgsql-hackers@lists.postgresql.org]> 解释您的问题,以便解决不足之处。
F.50.2. Description of Functions #
Table F.36 显示此模块提供的函数。这些函数提供了直接的 XML 解析和 XPath 查询。
Table F.36. xml2 Functions
Function Description |
xml_valid ( document text ) → boolean 分析给定的文档并返回 true(如果该文档是格式良好的 XML)。(注意:这是标准 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>可能为 XML 片段的值 1</itemtag><itemtag>值 2….</itemtag></toptag>如果 toptag 或 itemtag 为空字符串,則会省略相关标签。 |
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 对该文档求值查询,并返回多个值(以指定的分隔符分隔),例如 Value 1,Value 2,Value 3 (如果 separator 为 , )。 |
xpath_list ( document text , query text ) → text 这是一个包装器,针对上面的函数使用 , 作为分隔符。 |
F.50.3. xpath_table #
xpath_table(text key, text document, text relation, text xpaths, text criteria) returns setof record
xpath_table 是一个表函数,它针对一组文档中的每组文档评估一系列 XPath 查询,并将结果作为表返回。结果的第一列中返回原始文档表中的主键字段,以便结果集可以很容易地用于联接。参数将在 Table F.37 中描述。
Table F.37. xpath_table Parameters
Parameter |
Description |
key |
“键”字段的名称 — 这只是一个字段,用作输出表的首列,即它标识了每个输出行派生的记录(有关多个值的说明,请参阅以下备注) |
document |
包含 XML 文档的字段名称 |
relation |
包含文档的表或视图的名称 |
xpaths |
一个或多个 XPath 表达式,用 _ 分隔 |
_ |
criteria |
除了 XPath 字符串以外,这些参数都刚代入一条简单的 SQL SELECT 语句中,这样便可以获得一些灵活性 — 语句是
SELECT <key>, <document> FROM <relation> WHERE <criteria>
因此这些参数可以是 anything,在那些特定位置中有效。此 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. Multivalued Results #
xpath_table 函数假定每个 XPath 查询的结果可能是多值的,因此此函数返回的行数可能与输入文档的数目不同。返回的第一行包含每个查询的第一个结果,第二行包含每个查询的第二个结果。如果其中一个查询比其他查询的值少,则会返回 null 值。
在某些情况下,如果与可能会返回其他结果的 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 Functions #
如果已安装 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. Author #
此模块的开发由 Torchbox Ltd.(www.torchbox.com)赞助。它具有与 PostgreSQL 相同的 BSD 许可证。