金仓数据库 KingbaseES 插件参考手册 xml2
110. xml2
110.1. 插件xml2简介
xml2是KingbaseES的一个扩展插件,主要提供XPath查询和XSLT功能。
-
插件名为 xml2
-
插件版本 V1.1
在核心服务器中就已经有基于SQL/XML标准的XML相关功能,这些功能覆盖了XML语法检查和XPath查询。xml2同样支持这些功能,但是提供的API并不是完全兼容,保留xml2插件的目的是为了保持向后兼容。我们已经有计划将xml2从KingbaseES一个未来版本中移除,因此我们鼓励您尝试转换您的应用。
110.2. 插件xml2加载方式
CREATE EXTENSION xml2;
110.3. 插件xml2的参数配置
无需配置任何参数。
110.4. 插件xml2的使用方法
下表展示了xml2插件提供的函数。这些函数提供了直接的XML解析和XPath查询。所有参数都是text类型,为了简洁省略了参数类型。
函数 | 返回 | 描述 |
---|---|---|
xml_is_well_formed(document) | bool | 这个函数解析其参数中的文档文本并且在该文档是一个结构良好的XML时返回真。 |
xpath_string(document, query) | text | 在提供的文档上计算XPath查询,并且将结果造型为指定的类型。 |
xpath_number(document, query) | float4 | 在提供的文档上计算XPath查询,并且将结果造型为指定的类型。 |
xpath_bool(document, query) | bool | 在提供的文档上计算XPath查询,并且将结果造型为指定的类型。 |
xpath_nodeset(document, query, toptag, itemtag) | text | 这个函数在文档上计算查询并且把结果包装在XML标签中。如果toptag或者itemtag是一个空字符串,相关的标签会被忽略。 |
xpath_nodeset(document, query) | text | 与xpath_nodeset(document, query, toptag, itemtag)相似,但是结果忽略两种标签。 |
xpath_nodeset(document, query, itemtag) | text | 与xpath_nodeset(document, query, toptag, itemtag)相似,但是结果忽略toptag。 |
xpath_list(document, query, separator) | text | 这个函数返回多个值,并且用指定的分隔符分隔,例如分隔符是",",结果就是Value 1,Value 2,Value 3。 |
xpath_list(document, query) | text | 这是上面函数的一个包装器,它用","作为分隔符。 |
110.4.1. xpath_table
xpath_table(text key, text document, text relation, text xpaths, text criteria) returns setof record
xpath_table是一个表函数,它在一组文档中的每一个上计算一组 XPath 查询,并且将结果作为一个表返回。来自原始文档表的主键域被返回为结果的第一列,这样结果集可以被用于连接。
参数 | 描述 |
---|---|
key | “key”字段的名称 — 这只是被用作输出表中第一列的字段,即它标识每个输出行是来自于哪个记录 |
document | 包含XML文档的域的名称 |
relation | 包含文档的表或视图的名称 |
xpaths | 一个或多个XPath表达式,用英文竖线分隔 |
criteria | WHERE子句的内容,这不能被忽略,因此如果你想要处理关系中的所有行,可以使用true或1=1 |
这些参数(除了XPath字符串)会被替换到一个纯粹的SQL SELECT语句中,因此可以是特定位置上合法的任何内容。(注意:这种简单方法要求您验证任何用户提供的值,以避免SQL注入攻击)
SELECT <key>, <document> FROM <relation> WHERE <criteria>;
该函数必须被使用在一个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结果的字符串表示,并使用KingbaseES的输入函数来把它转换成整数(或者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;
110.4.1.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)
110.4.2. XSLT函数
如果安装了 libxslt,那么可以使用下列函数:
xslt_process(text document, text stylesheet, text paramlist) returns text
这个函数将XSL样式表应用于文档,并且返回转换过的结果。paramlist是一个被用在转换中的参数赋值列表,以 a=1,b=2
的形式指定。
注意:参数解析是非常简单的,参数值不能包含逗号!
还有一个双参数版本的xslt_process,它不会向转换传递任何参数。
110.5. 插件xml2卸载方法
DROP EXTENSION xml2;
110.6. 插件xml2升级方法
xml2扩展插件通常随着KingbaseES安装包一并升级。通常情况下用户无须单独升级该插件。
ALTER EXTENSION xml2 UPDATE TO new_version;