XML - 管理数据交换/XQuery
上一章 | 下一章 |
← XQL | Exchanger XML Lite → |
XQuery 是一种由万维网联盟 (W3C) 开发的查询语言,它使人们能够高效便捷地从原生 XML 数据库和存储 XML 数据的关系数据库中提取信息。
每个查询都包含一个引言和一个主体。引言建立了编译时环境,例如模式和模块导入、命名空间和函数声明以及用户定义的函数。主体生成整个查询的值。XQuery 的结构如图 1 所示。
图 1. XQuery 的结构 |
||
引言 |
注释 |
(: 示例版本 1.0 :) |
命名空间声明 |
declare namespace my = “urn:foo”; |
|
函数声明 |
declare function my:fact($n) { |
|
|
if ($n < 2) |
|
|
then 1 |
|
|
else $n * my:fact($n – 1) |
|
|
}; |
|
全局变量 |
declare variable $my:ten {my:fact(10)}; |
|
|
||
主体 |
构造的 XML |
<table>{ |
FLWOR 表达式 |
for $i in 1 to 10 |
|
return |
||
|
<tr> |
|
封闭表达式 |
<td>10!/{$i}! = {$my:ten div my:fact($i)} </td> |
|
|
</tr> |
|
|
} </table> |
2.1 XQuery 与 XPath 和 XSLT 的比较
XQuery、XPath、XSLT 和 SQL 都是优秀的查询语言。每种语言在不同的情况下都有其优势,因此 XQuery 无法替代所有任务中的它们。XQuery 建立在 XPath 表达式的基础上。XQuery 1.0 和 XPath 2.0 共享相同的数据模型、相同的函数和相同的语法。表 1 显示了每种查询语言的优缺点。
表 1. XQuery 与 XPath 和 XSLT 的比较
|
优势 |
缺点 |
XQuery |
1. 表达连接和排序 2. 以任意顺序操作值和节点的序列 3. 易于编写用户定义的函数,包括递归函数 4. 允许用户在查询中间构造临时 XML 结果,然后导航到该结果 |
1. XQuery 实现不如 XSLT 实现成熟 |
XPath 1.0 |
1. 用于寻址 XML 文档部分的便捷语法 2. 从现有 XML 文档或数据库中选择节点 |
1. 无法创建新的 XML 2. 无法仅选择 XML 节点的一部分 3. 无法引入变量或命名空间绑定 4. 无法处理日期值,计算数字集的最大值或对字符串列表进行排序 |
XSLT 1.0 |
1. 递归处理 XML 文档或将 XML 翻译成 HTML 和文本 2. 创建新的 XML 或现有节点的一部分 3. 引入变量和命名空间 |
1. 无法在不创建类似于 XQuery 的语言的情况下进行寻址 2. 无法处理值序列 |
2.2 XQuery 与 SQL 的比较
XQuery 在风格和语法上与 SQL 有相似之处。XQuery 和 SQL 之间的主要区别在于,SQL 专注于“扁平”行的无序集,而 XQuery 专注于值的序列和层次节点的有序序列。
3.1 FLWOR 表达式
FLWOR 表达式是 XQuery 的重要组成部分。FLWOR 的发音为“flower”。这个名字来自FOR、LET、WHERE、ORDER BY 和RETURN 子句,这些子句组织了表达式。FOR 和 LET 子句可以在任何顺序出现任意次数。WHERE 和 ORDER BY 子句是可选的。但是,如果使用这些子句,则必须按给定的顺序显示它们。RETURN 子句必须存在。
XQuery 允许您以类似于 SQL 的方式使用连接查询。此示例在示例 1 中被描绘为视频表和演员表之间的连接。
示例 1.
let $doc := . for $v in $doc//video, $a in $doc//actors/actor where ends-with($a, 'Lisa') and $v/actorRef = $a/@id order by $v/year return $v/title
LET 子句表示变量赋值。在本例中,查询将其初始化为 doc ('videos.xml'),或查询的结果将文档放置在数据库中。FOR 子句描述了一种迭代机制:一个变量依次处理所有视频,另一个变量依次处理所有演员。在本例中,查询处理视频和演员的配对。WHERE 子句选择您感兴趣的表。在本例中,您想知道演员是否出现在视频表中,且姓名以“Lisa”结尾。ORDER BY 子句以排序顺序获取结果。在本例中,您希望结果按视频的发布日期排序。表达式末尾的RETURN 子句通知系统您想要获取哪些信息。在本例中,您想要视频的标题。
3.2 条件表达式
XQuery 提供了 IF、THEN 和 ELSE 子句,即条件表达式。ELSE 子句是强制性的。原因是 XQuery 中的每个表达式都应该返回一个值。示例 2 中显示了一个查询,以检索所有书籍及其作者。您希望在头两个作者之后将其他作者作为“et-al”返回。
示例 2.
for $b in document("books.xml")/bib/book return if (count($b/author) <= 2) then $b else <book> { $b/@*, $b/title, $b/author[position() <= 2], <et-al/>, ...... $b/publisher, $b/price } </book>
此查询从 books.xml 中读取书籍数据。如果每本书的作者数量小于 2 或等于 2,则查询直接返回书籍。否则,查询创建一个包含所有原始数据的新的书籍元素,但查询只包含头两个作者,并将 et-al 元素附加到其中。position() 函数只返回头两个作者。$b/@*,XPath 表达式,指的是 $b 上的所有属性。
3.3 XQuery 函数和运算符
XQuery 包含大量函数和运算符。表 2 显示了常用的内置函数。您可以描述自己的函数,并且许多引擎也提供自定义扩展。
表 2. 常用的内置函数
函数 |
说明 |
数学 +, -, *, div, idiv, mod, =, !=, <, >, <=, >= floor(), ceiling(), round(), count(), min(), max(), avg(), sum() |
除法使用 div 而不是斜杠进行,因为斜杠表示 XPath 步进表达式。 idiv 是一个专门用于整数除法的运算符,它返回一个整数并忽略任何余数。 |
字符串和正则表达式 compare(), concat(), starts-with(), ends-with(), contains(), substring(), string-length(), substring-before(), substring-after(), normalize-space(), upper-case(), lower-case(), translate(), matches(), replace(), tokenize() |
compare() 指示字符串排序。 translate() 执行字符的特殊映射。 matches()、replace() 和 tokenize() 使用正则表达式查找、操作和拆分字符串值。 |
日期和时间 current-date(), current-time(), current-dateTime() +, -, div eq, ne, lt, gt, le, gt |
XQuery 具有许多用于日期和时间值的特殊类型,例如 duration、dateTime、date 和 time。在大多数情况下,您可以像处理数字一样对其进行算术运算和比较运算。两个字母的缩写代表等于、不等于、小于、大于、小于或等于以及大于或等于。 |
XML 节点和 QNames node-kind(),node-name(),base-uri() eq,ne,is,isnot,get-local-name-from-QName(),get-namespace-from-QName() deep-equal() >>,<< |
node-kind() 返回节点的类型(例如“元素”)。node-name() 返回节点的 QName,如果存在的话。base-uri() 返回此节点所在的 URI。 节点和 QName 值也可以使用 eq 和 ne(用于值比较)进行比较,或者使用 is 和 isnot(用于身份比较)。deep-equal() 根据两个节点的完整递归内容进行比较。 << 运算符在左操作数在文档顺序中preceeds右操作数时返回 true。>> 运算符是后续比较。 |
序列 item-at(),index-of(),empty(),exists(),distinct-nodes(),distinct-values(),insert(),remove(),subsequence(),unordered()。position(),last() |
item-at() 返回给定位置的项,而 index-of() 尝试为给定项查找位置。 empty() 在序列为空时返回 true,exists() 在序列不为空时返回 true。 dictinct-nodes() 返回一个序列,其中完全相同的节点被移除,而 distinct-values() 返回一个序列,其中任何重复的原子值被移除。 unordered() 允许查询引擎在不保留顺序的情况下进行优化。 position() 返回当前正在处理的上下文项的位置。 last() 返回最后一项的索引。 |
类型转换 string(),data(),decimal(),boolean() |
这些函数在可能的情况下返回给定类型的节点。 data() 返回节点的“类型化值”。 |
布尔值 true(),false(),not() |
在 XQuery 中没有“true”或“false”关键字,而是使用 true() 和 false() 函数。 not() 返回其参数的 boolean 取反。 |
输入 document(),input(),collection() |
document() 根据 URI 参数返回节点的文档。 collection() 根据字符串参数(可能是多个文档)返回集合。 input() 返回引擎提供的通用输入节点集。 |
4. 参考资料
[edit | edit source]本章内容摘自以下列表。
- X Is for XQuery, Jason Hunter: http://www.oracle.com/technology/oramag/oracle/03-may/o33devxml.html
- An Introduction to the XQuery FLWOR Expression, Michael Kay: http://www.stylusstudio.com/xquery_flwor.html
- Learn XQuery in 10 Minutes, Michael Kay: http://www.stylusstudio.com/xquery_primer.html
- XQuery: The XML Query Language, Michael Brundage, Addison-Wesley 2004
5. 有用链接和书籍
[edit | edit source]- W3C XML Query (XQuery): http://www.w3.org/XML/Query
- XQuery 最新版本:http://www.w3.org/TR/xquery/
- XQuery 1.0 和 XPath 2.0 函数和运算符:http://www.w3.org/TR/xpath-functions/
- XQuery 1.0 和 XPath 2.0 数据模型 (XDM):http://www.w3.org/TR/xpath-datamodel/
- XSLT 2.0 和 XQuery 1.0 序列化:http://www.w3.org/TR/xslt-xquery-serialization/
- XML Query 用例:http://www.w3.org/TR/xquery-use-cases/
- XML Query (XQuery) 需求:http://www.w3.org/TR/xquery-requirements/
- XQuery: The XML Query Language, Michael Brundage, Addison-Wesley 2004
另请参阅
[edit | edit source]- XQuery 教程和食谱维基教科书 这本维基教科书包含许多 XQuery 小示例,并链接到可用的 XQuery 应用程序。