xquery简介
注意:本文在2005年12月所做的更新包含了XQuery规范的最新更改:八个工作草案现在已达到W3C“候选推荐书”的状态,使该规范整体上更接近最终的建议书。 主要的全文本文件于2004年首次发布,最近已更新。 更新工具的需求工作草案以及有关构建XPath / XQuery标记程序的草案均于2005年首次发布。XQuery功能的数量在不断增长,XQuery实现者列表和XQuery实现者列表也在不断增加。开发人员可用的基于Web的资源数量。
经过6年漫长的发展,W3C的“推荐”路线一直沿用XQuery规范,呈现出好莱坞特许经营的神话般和持久的外观-“星球大战”和“指环王”系列浮现在脑海。 XQuery的起源可追溯到1998年W3C赞助的查询语言研讨会,来自行业,学术界和研究团体的代表聚集在波士顿,就他们认为对于查询语言重要的功能和要求发表了看法。 XML。
66个演示文稿都可以在线获取,以供那些对历史观点感兴趣的人使用(请参阅参考资料 ),这些演示文稿主要来自两个截然不同的选区的成员:主要在XML as-document领域工作的人(主要反映了XML的原始根源)。以及使用XML as-data的对象 -后者主要反映了XML在中间件领域(前端传统关系数据库)中的地位不断提高。
特别是一个演讲,俄勒冈大学研究生院的David Maier简洁明了的演讲,题为“用于XML查询语言的数据库Desiderata”,特别有助于波士顿不久后成立的查询语言工作组的思考。
这些年来,尽管其人口数量有所波动,但按照W3C标准,工作组人数众多(有人告诉我,只有议定书工作组的成员人数更多)。 它由30多家会员公司组成,反映了数据和文档选区的观点。 XML查询语言标准现在已经很接近合并为最终形式(很长一段时间了),该标准能够很好地管理两个社区的需求和观点。
XML用户最熟悉的XQuery关键组件是XPath,它本身是W3C规范。 单独存在的单独XPath位置路径(例如,“ // book / editor”表示“在当前数据集中查找所有书籍编辑器”)是完全有效的XQuery。 在数据方面,XQuery的类似SQL的外观和功能应该受到来自世界关系方面的人们的欢迎和熟悉。
XQuery从被子开始。 Quilt主要是用户级语法的测试工具,由工作组的三个勤奋且高度可见的成员带头:Jonathan Robie,Don Chamberlin和Daniela Florescu。 反过来,Quilt是基于整个工作组在定义需求,用例以及基础数据模型和代数方面的共同努力。
Robie,Chamberlin和Florescu引用了许多语言对Quilt的设计产生影响,包括XQL,XML-QL和SQL。 如果你有兴趣在计算机语言如何发展,请阅读“XML查询语言:经验及示例”(见相关信息 ),一个有用的文件,其中规定第一两种语言的一个很好的比较概况,两个人一起叫YaTL和Lorel 。 作者Mary Fernandez,Jerome Simeon和Phil Wadler本身都是工作组的成员。
鉴于数据社区和文档社区的观点各异,并且工作组奠定了坚实的基础,因此花大量时间将规范的大部分内容公诸于众也就不足为奇了。 一方面,W3C工作组的内部程序是保密的,并且查询语言工作组在2001年2月中之前的大部分工作都是秘密进行的。
需求文档和数据模型工作草稿是在很早的时候发布的,但是工作组的发布机构确实在2001年2月开始发挥作用,当时大量文档开始出现。 随后在2001年进行了两次重大更新,此后每年更新三到四次,但2004年除外,当时该小组只发布了一次。
随着今年最近增加了有关更新机制的需求文档,以及关于如何为XQuery语言实现者构建标记器的简短说明,现在总共有16个文档(包括XSLT规范,已在XML Query Web上列出)网站(出于某种原因,我不清楚),并且不久之后可能会成为一个完整的网站。 肯定会出现更新语言文档。
总体上描述和定义XQuery的文档集包括:
这些文件(在所有引用的相关信息 )代表工作的巨大身体。 XQuery 1.0:XML查询语言是集合中的关键文档,但是其他所有文档都构成了一种令人惊讶的详细说明和全面支持的语言。 据我所知,这是W3C提出的最复杂的规范集(尽管可以想到XML Schema,但这是另一回事了……)。
如果您是第一次盯着这么多的文档并且想知道从哪里开始,我可以推荐两种可能的方法。 您可以从中央XQuery 1.0文档开始。 它具有良好的介绍性概述,并详细介绍了该语言的许多功能。 另一种方法是从选择用例工作草案开始。 本文概述了XQuery具有适用性的许多实际场景。 每个用例都针对特定的应用程序域,并列出针对该域的样本数据提出的多个XQueries。 如果您喜欢查看实际工作语法的具体示例,那么这些代码段非常有用。 第三种方法是浏览“函数和运算符”工作草案中列出的许多内置函数,这对您已经对语言有最少的了解才是最好的。
过去几年中,还出现了两本出色的书,用以解释该规范的来龙去脉,均来自Addison-Wesley:“来自专家的XQuery”提出了许多有关XQuery相关主题的详细技术文章。工作组,而“的XQuery:XML查询语言”是由微软的迈克尔·布伦戴奇的迫切可读参考工作(见相关主题 )。
XQuery实际上是三种语言的一种:
数据模型和形式语义工作草案共同为XQuery提供了精确的理论基础。 这两个文档详细介绍了查询代数,一组精确的定义,这些定义以正式术语定义了XQuery查询应在其上进行操作的核心实体,以及各种语言运算符可以对这些操作数进行处理的方式的表述。 除非您是查询引擎实现者,具有重大的口袋保护或者只是喜欢使用复杂的正式系统,否则这可能对您不感兴趣。
提供的一种映射使实现者可以将表面语法功能直接重铸到基础代数中。 您可以实现实际上直接讲代数的查询处理器(尽管我认为这更多是用于概念验证),正如一些供应商在XML贸易展上所展示的那样。 “ 相关主题 ”中的链接指向这些基于代数的引擎之一的在线演示版本。
代数还提供了详细说明如何将两个复杂表达式优化和转换为更简单等效项的规则。 尽我所能告诉我(我不是语言理论家,形式语义学文档远非易读),这两者都是好东西。 大型数据库供应商尤其会喜欢查询语言体系结构,该体系结构从头开始设计为既可优化又高效。
代数还提供了一个悬挂类型信息的地方。 XQuery是强类型的:如果您的数据具有关联的W3C XML模式,则处理器可以针对该模式进行验证,并为查询引擎提供有关文档中节点数据类型的后模式验证信息集(PSVI)信息,同时使用在“ XML模式第2部分:数据类型”中声明的类型以及您自己的用户定义类型。 代数具有静态和动态类型检查功能。 例如,引擎可以使用PSVI派生的类型信息在编译时(当分析查询的语法正确性时)静态检查查询表达式的数据类型。 确定查询在周期的早期是类型无效的,这使得对大型数据集进行潜在昂贵(且毫无结果)的搜索的需求减少。 XQuery规范的许多工作都涉及涉及类型的部分语言的语法和语义。
XQuery与XPath 2.0共享一个通用的数据模型,这一事实反映在数据模型文档的标题有些笨拙:“ XQuery 1.0和XPath 2.0数据模型”(以及工作组开始使用更为明显的首字母缩写词的原因, XDM,以引用数据模型)。 此时,XPath 2.0即将完全成熟。 数据模型在XPath处理器感兴趣的XML文档中描述了核心信息,并且XPath的step操作的最终语法和语义现在已基本完成。 完整的规范由查询语言和XSL工作组共同拥有,并且两个组都需要就XPath 2.0的外观达成共识。 有时在政治和技术上都充满挑战。 但是,如果达成共识的道路有时是坎rock的,那么这两个团体似乎都在没有太多明显不适的情况下进行导航(至少从局外人的天真视角来看)。
作为为什么从XPath 1.0过渡到2.0如此有趣的一个示例,请考虑以下几点:XPath 1.0是一种基于集合的表达语言。 节点集是XPath 1.0中的四种数据类型之一,它就是:集。 根据定义,集合是无序的,并且不包含重复的成员。 另一方面,XPath 2.0是基于序列的。 相比之下,XPath 2.0中的节点序列(按类推称为节点序列 )具有顺序,并且允许重复。 这些差异的后果是工作组必须共同解决的许多问题中的一个,因为他们将自己和XPath 2.0统一起来,正如行话所说。
现在已经解决了所有剩余的实质性问题。 按照W3C的说法,构成XQuery规范的七个关键文档现在已成为候选建议,这一事实从官方的角度来说,意味着XQuery现在被视为“稳定且适合实施”。
在正式的W3C推荐程序方面,已经解决了在上一个“上次致电”期间提出的所有问题,并且工作组现在正在寻求行业供应商提供XQuery的主要功能可以实现的真实验证。 为此,实施者可以通过工作组提供的测试套件来运行其实施。 候选推荐阶段中两个或多个供应商未实现的那些功能有被从规范中删除的风险。 当前的高风险功能列表包括:
XQueryX是表面语言的一种替代基于XML的语法的规范,是XQuery文档系列的较早版本之一。 对XQuery的要求之一指出, 可能有多种语法-听起来好像工作组在对冲其赌注-如果是这样,则其中之一必须方便人类阅读和书写; 另一个必须以XML表示。 XQueryX是工作组对后者要求的答案。
拥有基于XML的查询表示具有XML的所有显而易见的优点:它使标准工具可以轻松解析,生成和查询查询的内容。 例如,这在您进行源代码级的优化或转换时可能很有用,而这可能又取决于能否轻松地检查查询中特定语法结构的能力。 XML擅长于此类任务。
XQueryX是该语言的形式语法的XML的近乎一对一的映射。 考虑到语法的复杂性,这使得XQueryX 非常冗长,以至于人类几乎无法阅读。 令人高兴的是,机器-语言的预期接收者-不会抱怨这种事情。 清单1和2提供了一个简单查询的比较,该查询首先以标准XQuery语法表示,然后以其XQueryX对应形式表示。 注意显着的类固醇增加因子。
<bib>
{
for $b in doc("http://bstore1.example.com/bib.xml")/bib/book
where $b/publisher = "Addison-Wesley" and $b/@year > 1991
return
<book year="{ $b/@year }">
{ $b/title }
</book>
}
</bib>
清单2显示了等效的XQueryX。 由于篇幅太长,我省略了大约四分之三的清单。 直接从XQueryX工作草案中提取的完整清单包含132行:
<?xml version="1.0"?>
<xqx:module xmlns:xqx="http://www.w3.org/2005/XQueryX" ... >
<xqx:mainModule>
<xqx:queryBody>
<xqx:elementConstructor>
<xqx:tagName>bib</xqx:tagName>
<xqx:elementContent>
<xqx:flworExpr>
<xqx:forClause>
<xqx:forClauseItem>
<xqx:typedVariableBinding>
<xqx:varName>b</xqx:varName>
</xqx:typedVariableBinding>
<xqx:forExpr>
<xqx:pathExpr>
<xqx:argExpr>
<xqx:functionCallExpr>
<xqx:functionName>doc</xqx:functionName>
<xqx:arguments>
<xqx:stringConstantExpr>
<xqx:value>http://bstore1.example.com/bib.xml</xqx:value>
</xqx:stringConstantExpr>
</xqx:arguments>
</xqx:functionCallExpr>
</xqx:argExpr>
<xqx:stepExpr>
<xqx:xpathAxis>child</xqx:xpathAxis>
<xqx:nameTest>bib</xqx:nameTest>
</xqx:stepExpr>
<xqx:stepExpr>
<xqx:xpathAxis>child</xqx:xpathAxis>
<xqx:nameTest>book</xqx:nameTest>
</xqx:stepExpr>
</xqx:pathExpr>
</xqx:forExpr>
</xqx:forClauseItem>
</xqx:forClause>
...
2001年6月,当我第一次撰写现有XQuery实现的摘要时,就在第一次重大发布迭代之后,只有两种实现可用:我自己的一个非常早期的实现和Microsoft的一个。 那给了我一个给自己开玩笑的机会,开玩笑说比尔·盖茨和我都在争取市场地位。 这次大约四年了,以后再进行任何数量的工作草案,这种笑话不再有效。 现在有将近四打实现,以及大量相关产品和工具。
查看当前可用内容的最佳位置是XML Query主页(请参阅参考资料 )。 列表非常活跃,随着兴趣和势头的增强以及规范越来越接近“建议”状态,我希望看到定期出现新的实现。
现在,根据一个实际示例快速浏览一些XQuery功能。 这是一个非常简单的查询,对用例文档中的一个规范样本文件进行操作。 此查询说明了XQuery进行投影 (选择数据集中符合所需条件的节点子集)和进行转换 (生成与要查询的文档不同的输出文档)的能力。 XQuery允许您既指定要查找的内容,又指定其输出格式在同一查询中应为什么样。
清单3显示了该查询所针对的文档片段:
<bib>
<book year="1994">
<title>TCP/IP Illustrated</title>
<author><last>Stevens</last><first>W.</first></author>
<publisher>Addison-Wesley</publisher>
<price>65.95</price>
</book>
<book year="1992">
<title>Advanced Programming in the Unix environment</title>
<author><last>Stevens</last><first>W.</first></author>
<publisher>Addison-Wesley</publisher>
<price>65.95</price>
</book>
<book year="2000">
<title>Data on the Web</title>
<author><last>Abiteboul</last><first>Serge</first></author>
<author><last>Buneman</last><first>Peter</first></author>
<author><last>Suciu</last><first>Dan</first></author>
</book>
...
</bib>
您希望生成的输出文档(有点修饰)看起来像清单4所示 :
<results>
<book authorCount="1">
<author>Stevens</author>
</book>
<book authorCount="1">
<author>Stevens</author>
</book>
<book authorCount="3">
<author>Abiteboul</author>
<author>Buneman</author>
<author>Suciu</author>
</book>
...
</results>
这是查询本身。 它的工作是浏览查询文档中的所有书籍,生成上面显示的结果文档,其中包括:在每个输出的新<book>
标记中包含计算的authorCount
属性; 并丢弃原始信息中的大部分剩余信息,仅保留每个作者的姓氏。
(请注意,这里我使用术语“查询的文档”(单数)。这是一个简化:XQuery的数据模型还能够处理文档集合以及部分片段。)
<results>
{
for $book in doc( "http://uri-for-book-dataset" )//book
let $authors := $book/author
return
<book authorCount="{ count($authors) }">
{
for $author in $authors
return
<author>{ $author/last/text() }</author>
}
</book>
}
</results>
在清单5中 , doc()
函数用于将查询指向要查询的XML文档。 它在XQuery和XPath数据模型(XDM)的词汇表中返回一个document node
。
剖析查询
这是此查询的一些有趣功能:
for / let表达式
该示例包含两个嵌套的for
循环和一个let
。 外for
通过每个从路径表达式的膨胀,所产生的节点的迭代doc(...)//book
,隔离每个<book>
在名为可变反过来节点$book
。 let
表达式依次在名为$authors
的变量中拾取每本书的所有<author>
子节点。 $authors
变量保存一个节点序列 ; $book
和$author
变量都包含单个节点。
重要的是要注意,这些变量未分配 ,它们是绑定的 。 区别是微妙的,但很重要:绑定变量后,其值是不变的。 这样可以防止由于动态分配变量值而导致的不良后果。 另一个潜在的好处是,在处理过程中可以(在某种程度上)重新排列包含变量的行,从而使精明的引擎可以优化其查询。
for
和let
表达式是FLWOR
(发音为flower )表达式的子组件。 该首字母缩写词代表其五个主要组成部分子句: for
- let
- while
- order by
- return
。 在清单6中 , FLWOR
表达式的形式语法:
FLWORExpr ::= (ForClause | LetClause)+ WhereClause? "return" Expr
表明它是一个非常复杂的表达式类型,能够生成大量可能的查询实例。 如该结果所示, "return"
关键字后面的Expr
词条本身可以用另一个FLWOR
表达式代替,这样FLWOR
可以像无限长的乐高积木一样在最后无限地串在一起。 用任何其他表达式类型替换Expr
术语是使XQuery 可组合并使其具有丰富的表达能力的原因。 XQuery中有大量的表达式类型,每种类型都可以在需要更通用的Expr
地方插入语法中。
更平凡的是,最终return
语句终止了FLWOR
序列。 在上述查询的情况下,可以使用一个附加的内部return
值作为方便点,以便为要输出的每个<book>
插入一个元素构造函数。
元素构造函数
该查询包含三个元素构造函数。 元素<results>
, <book>
和<author>
是通过直接将文字尖括号XML写入查询本身的方式来动态生成的。
大括号( {
和}
)在必要时用于消除文字文本内容与元素构造函数中需要求值的子表达式的歧义。 例如,如果您在清单7中发出文字表达式,则不需要使用花括号来分隔内部和外部标签。
<authors>
<author>
...
顺便说一下,大括号是在2001年6月修订的表面语言语法中引入的。 较早版本的语法不需要它们。 花括号是语言在朝着推荐标准发展的过程中如何变化和发展的一个很好的例子。
属性构造函数
清单8中的代码显示了内联属性构造函数的用法。 count()
函数返回每本书中包含的<author>
元素的数量。 再次注意花括号,在此用于将需要从其周围文字XML求值的表达式封锁起来。 使用引号来分隔属性构造函数中的属性值是该规范演变时所做的另一项更改的示例。
<book authorCount="{ count($authors) }" >
内置功能和运算符
count()
是内置函数的示例。 “函数和运算符”草稿列出了数十个不同组中的近225个函数和运算符,它们在各种数据类型上进行构造和操作,包括数字,字符串,布尔值,日期和时间,qname,节点和序列。
清单9中的表达式使用text()
运算符填充每个<author>
元素的内容,并从其封闭的<last>
元素中提取姓氏的文本。 如果您只是直接使用$author/last
,那么也会得到封闭标签,在这种情况下,这是不需要的。
<author>{ $author/last/text() }</author>
翻译自: https://www.ibm.com/developerworks/xml/library/x-xquery/index.html
xquery简介