1 / 43

6. XQuery

6. XQuery. XQuery ( XML Query )是一种专门用于 XML 半结构化数据的查询语言, W3C 于 2007 年 1 月 23 日正式发布了 XQuery 1.0 规范( XQuery 1.0 : An XML Query Language , http://www.w3.org/TR/xquery/ )。 与其他半结构化数据查询语言相比,由于它是 W3C 的推荐标准,所以受到了业界广泛的支持。目前,由不同的软件提供商所实现的 XQuery 软件包大约有 40 多种,适用于不同的开发语言、平台和环境。.

lars-kerr
Download Presentation

6. XQuery

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. 6. XQuery • XQuery(XML Query)是一种专门用于 XML 半结构化数据的查询语言,W3C 于 2007 年 1 月 23 日正式发布了XQuery 1.0 规范(XQuery 1.0 : An XML Query Language,http://www.w3.org/TR/xquery/)。 • 与其他半结构化数据查询语言相比,由于它是 W3C 的推荐标准,所以受到了业界广泛的支持。目前,由不同的软件提供商所实现的 XQuery 软件包大约有 40 多种,适用于不同的开发语言、平台和环境。

  2. 6.1 XML 数据查询语言 • 对于 XML 数据,查询语言的基本任务与关系数据库查询语言是相同的,主要包括如下几个方面: • 检索数据 • 聚集或汇总数据 • 连接来自不同数据源的数据 • 插入新的数据、更新或删除已有的数据 • 修改数据本身的结构 • 支持某些过程操作

  3. 6.1.1 从结构化数据查询语言 SQL 到半结构化查询语言 XQuery • SQL 结构化查询语言是用于关系数据库系统的标准查询语言,包括数据定义语言 DDL、数据操纵语言 DML、数据控制语言 DCL。 • 是否可以直接在 SQL 的基础上适当地增加一些特性或语法,使其用于查询 XML 数据呢?因为关系数据和半结构化所使用的底层数据结构完全不同,无法使用原有的 SQL。

  4. 关系数据与XML数据之间的区别

  5. SQL/XML • ISO/IEC 9075 系列标准的最新版本 SQL 2003 中,作为其中的第 14 部分“XML 相关规范(SQL/XML)”,第一次在 SQL 语言中正式引入了 XML 技术,它指出通用数据库管理系统应如何支持 XML 的存储、检索、转换,为基于 XML 的数据库应用的开发、集成、部署和运行提供了完整的集成解决方案。 • 这些 SQL/XML 功能的作用是将存储于关系数据库表结构中的数据映射为 XML 层次结构,而并不是对原始的 XML 数据进行查询检索。

  6. XML 数据查询语言的特征 • 平台一致性 • 面向 XML 的(XML-Centric) • 具备集合处理的能力 • 易于使用 • 广泛的适应性

  7. 6.1.2 XQuery 的诞生 • 关系数据库中的 SQL/XML 无法完成对半结构化数据的查询检索。因此,出现了许多的半结构化数据查询语言,包括 XQL、XML-QL、XSQL、UnQL、StruQL、YATL、LOREL、以及 Quilt,其中 Quilt 是 XQuery 的前身。 • Quilt 最初作为用户级语法的测试工具,在定义需求、用例以及底层数据模型和代数方面进行了很多积极的努力,它本身借用了其他半结构化查询语言的一些优点,比如引入了路径表达语法、引入了变量绑定、提供了构造查询结果的语句、支持嵌套查询等。

  8. XQuery 1.0 • 2007 年初,XML 查询工作组提交了正式的 XQuery 1.0 规范。 • XQuery 是一种用于文件和数据库中基于 XML 文档内容的新型查询语言,构建于 Quilt 查询语言的基础之上,从而综合了其他一些查询语言的优势和特点。 • XQuery 是由一些 SQL 专家制订,它的出现是因为 SQL 这种用于关系数据查询的语言无法完美地处理 XML 文档。

  9. XQuery 的特点 • 作为 W3C 发布的一种规范,XQuery 与 W3C 所发布的其他规范之间具有很好的兼容性,比如 XQuery 使用与 XML Schema 一致的内置数据类型系统、并支持使用 XML Schema 提供自定义的类型信息、XQuery 1.0 依靠 XPath 2.0 路径表达式进行对层次化文档的操作、XQuery 1.0 与 XPath 2.0 使用一组公共的操作符和函数。 • 与 XSLT 相比,XQuery 具有以下的特征: • 易于使用 • 更加简洁 • 强类型语言 • 更广泛地使用场景

  10. 6.1.3 XML 格式的 XQuery 查询语言 • 查看 XMLSPY 中的 XQuery 文档。 • XQuery 也支持面向机器处理的 XML 格式,这就是 XQueryX(XML Syntax for XQuery 1.0 (XQueryX))。 • XQueryX 是 W3C XML 工作组开发的另一个规范,它是一种通过 XML 语法描述 XQuery 的标记语言。 • XQueryX.xml for$tindoc("bib.xml")/bib/book/title return$t

  11. 6.2 XQuery 基本语法和相关概念 • XQuery 相当于查询 XML 数据的 SQL 语言,并且 XQuery 规范本身就是由一些 SQL 专家们制订,所以它的基本语法与 SQL 语言非常相似。 • 与 SQL 中的 select 语句向对应,XQuery 中提供了 FLOWR 语句,可以完成对 XML 数据的查询、筛选、排序。

  12. 6.2.1 XQuery 基本语法 for$bindoc("bib-demo1.xml")/bib/book let$t := $b/title, $a := $b/author where$a/last="Stevens" orderby$t return<result> { $t } { $a } </result> SELECT column_list FROM table_source ORDER BY order_by_expression WHERE search_condition <?xml version="1.0" encoding="UTF-8"?> <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</title> <author><last>Stevens</last><first>W.</first></author> <publisher>Addison-Wesley</publisher> <price>65.95</price> </book> </bib> <result> <title>Advanced Programming</title> <author><last>Stevens</last><first>W.</first></author> </result> <result> <title>TCP/IP Illustrated</title> <author><last>Stevens</last><first>W.</first></author> </result>

  13. FLOWR 表达式 • FLOWR 表达式是 XQuery 查询计划基本形式 • XQuery 查询计划的逻辑组成部分,其中包含: • FOR 子句、 LET 子句、 WHERE 子句、 ORDER BY 子句、 RETURN 子句 • XPath 路径表达式和内置函数 • 各种自定义函数 • 命名空间

  14. for 子句 • SELECT ... FROM ... 用于指定从某个数据库表中检索若干列的内容;严格地说,这个操作的执行过程是,按照实际存储顺序(或索引结构)、依次访问该数据库表中的每一条记录,并从中取出指定列的内容,然后再执行后续的操作。如果单独考虑 SELECT ... FROM ...,它实际上是一个在目标数据集合中进行循环遍历的取值过程,以便对所取出的数据进行进一步的筛选和排序等操作。 • 在 XQuery 中,for 子句用于完成类似的工作,它也相当于高级程序设计语言中的 for 循环。

  15. for 子句中的范围变量 • 在 for 子句中,$variable_name 表示声明一个范围变量(range variable),然后为这个范围变量指定取值范围的集合,依次进行绑定。 • 比如,flwor-demo1.xquery 中的“for$bindoc("bib-demo1.xml")/bib/book ”,这表示 $b 的取值范围为 bib-demo1.xml 中的两个 book 节点(使用了关键字 in)。在执行该查询计划时进行循环遍历取值,分别取 book1、book2,以便对所取出的数据节点进行进一步的筛选和处理等操作。

  16. let 子句 • 类似于 SQL 中的 DECLARE 和 SET 语句,用于定义一个局部变量,并为其赋值。 Declare @i as int Set @i = 100 let$ias xs:integer := 100 • let 中的普通变量与 for 中的循环变量不同,它的取值仅进行一次性地绑定,而不是循环依次绑定。

  17. 有关 for 和 let 子句的详细说明 • 参见 for-and-let.xquery。

  18. 6.2.3 where 语句 • where 语句可以指定一系列的判断条件,根据 for 和 let 语句所生成的变量绑定元组进行筛选。 • where 语句是可选的,并且判断条件应该得到一个有效的布尔值(true 或 false),如果判断条件的计算结果为 true,则保留该元组;否则,则放弃该元组。

  19. where 语句的使用 • 比如下面的两个查询是完全等价的。 for$bindoc("bib-demo1.xml")/bib/book where$b/author/last="Stevens" return<result> { $b/title } </result> for$bindoc("bib-demo1.xml")/bib/book[author/last = "Stevens"] return<result> { $b/title } </result> • 可以使用 XPath 表达式中的判定谓词来取代 where 语句中的某些判断条件,有关 XPath 的判定谓词,曾在第 4 章中进行了详细地介绍。当然,从可读性的角度来说,建议尽可能使用前面一种方法书写。

  20. where 语句中布尔值的计算 ① 如果操作数是一个空序列(( )),那么转换将返回 false。 ② 如果操作数是一个序列,并且其中的第一项是节点,那么转换将返回 true。 ③ 如果操作数是一个仅包含单个原子值项目的序列,并且这个项目的类型为 xs:boolean,那么转换将返回该项目的值。 ④ 如果操作数是一个仅包含单个原子值项目的序列,并且这个项目的类型为 xs:string、xs:anyURI、xs:untypedAtomic,那么对于长度为零的值,转换将返回 false;否则返回 true。 ⑤ 如果操作数是一个仅包含单个原子值项目的序列,并且这个项目的类型为数值类型,那么对于非零的值,转换将返回 true;否则返回 false。 ⑥ 在任何其他的情况下,转换将产生类型错误。

  21. 布尔值计算的示例 根据上述的规则,下面的 where 语句将返回 true: 规则 ②:where (<a/>,<b/>) 规则 ③:where ("true"castas xs:boolean) 规则 ④:where ("false") 规则 ⑤:where (123) 根据上述的规则,下面的 where 语句将返回 false: 规则 ①:where ( ) 规则 ③:where ("false"castas xs:boolean) 规则 ④:where ("") 规则 ⑤:where (0) 根据上述的规则,下面的 where 语句将产生类型错误: 规则 ①、规则 ② 和规则 ⑥(非空序列,并且包含多个项目,但第一个项目不是节点): where (123,<a/>)、where ("true"castas xs:boolean,<a/>)

  22. order by 语句 • order by 语句是 XQuery 提供指定结果次序的功能;如果没有order by子句,结果的次序由 for 和 let 子句、以及排序模式决定。order by 语句中可以指定排序是 ascending 或 descending,缺省情况为 ascending 方式。 • 在 order by 语句中可以同时指定多个排序标准,首先按照第一标准进行排序,如果出现相等的情况,再依次按照后续的标准进行排序。

  23. order by 语句的基本使用 • 对于排序,循环操作(使用 for 语句)是必需的。 for$bin fn:doc("bib.xml")/bib/book orderby$b/title return<result> { $b/title } </result> let$b := fn:doc("bib-demo1.xml")/bib/book orderby$b/title return<result> { $b/title } </result>

  24. order by 语句的示例 • students.xml + students.xsd • orderby.xquery

  25. return 语句 • 在 FLOWR 中,return 语句为候选结果集中的每一个项计算一次,这些计算结果连接形成 FLWOR 表达式的结果。 • return 语句返回结果的顺序由排序模式、或者 order by 语句决定。 • 可以输出任何文本信息,包括 html、xml、xhtml、纯文本等各种形式。 • XQuery 提供了一些构造方法,以便在查询中创建 XML 结构,即创建元素、属性、文档、文本、注释和处理指令节点。这些构造方法主要分为两大类:直接构造方法(类似于 XML 形式的表示方法);计算构造方法(使用带括号的表示方法)。

  26. 一、直接构造方法 • 直接构造方法就是直接在 XQuery 查询计划中合适的位置按照 XML 的格式编写相应的内容。 • XQuery 文件的后缀名通常为 .xq 或者 .xquery,并不是一个 XML 文档。经过 XQuery 查询引擎处理之后,将直接输出其中所包含的类似 XML 格式的直接编码,从而在结果 XML 文档中形成相应的组成部分(包括元素、属性、文本、以及注释等等)。

  27. ① 元素及其文本内容的直接构造 ... return<result> { $t } { $a } </result> <results> { for$bindoc(“bib-demo1.xml”)/bib/book let$t := $b/title, $a := $b/author where$a/last=”Stevens” orderby$t return<result> { $t } { $a } </result> } </results>

  28. ② 属性的直接构造 I. <shoe size="7"/> 结果为<shoe size="7"/> II. <shoe size="{7}"/> 结果为<shoe size="7"/> III.<shoe size="{( )}"/> 结果为<shoe size=""/> IV.<chapter ref="[{1, 5 to 7, 9}]"/> 结果为<chapter ref="[1 5 6 7 9]"/> V.let$hat := <hat size="23"/> return<shoe size="As big as {$hat/@size}"/> 结果为 <shoe size="As big as 23"/>

  29. ③ 其他内容的直接构造 let$salary := 1000 return <income xmlns = "http://mycompany.org"> <!-- From 2006 to 2007 --> <?basis time="monthly"?> {$salary} </income> 其结果为: <income xmlns="http://mycompany.org"> <!-- From 2006 to 2007 --> <?basis time="monthly"?> 1000 </income>

  30. 二、计算构造方法 • 直接构造方法存在一定的局限性。 • XQuery 中构造 XML 内容的另一种方法是计算构造方法,通过采用一系列的计算构造语法,可以构造各种各样的 XML 内容。

  31. ① 元素及其文本内容的计算构造 CompElemConstructor ::= "element" (QName | ("{" Expr "}")) "{" ContentExpr? "} "  ContentExpr ::= Expr • 使用计算构造方法来构造元素,首先使用关键字 “element”,然后以硬编码的方式指定该元素的名称 QName(限定的名称,可以包含命名空间前缀)、或者使用表达式 (“{” Expr “}”) 动态地计算出该元素的名称,最后使用内容表达式 “{” ContentExpr? “}” 计算出该元素的内容(如果没有表达式 ContentExpr,则该元素为空元素)。 • 在 XML 中,元素可以包含子元素,所以某个元素的 CompElemConstructor 中可能嵌套地包含其他元素的 CompElemConstructor。

  32. 元素计算构造的示例 let$salary := 1000 return<income>{$salary}</income> let$salary := 1000 returnelement income {$salary} for$nodein (<student>WangFang</student>,<city>Beijing</city>) returnelement {concat("new", node-name($node))} {data($node)} <newstudent>WangFang</newstudent> <newcity>Beijing</newcity> for$nodein (<student>WangFang</student>,<city>Beijing</city>) return element {concat("new", node-name($node))} {element {concat("sub", node-name($node))} {data($node)} } <newstudent> <substudent>WangFang</substudent> </newstudent> <newcity> <subcity>Beijing</subcity> </newcity>

  33. ② 属性的计算构造 CompAttrConstructor ::= "attribute" (QName | ("{" Expr "}")) "{" Expr? "}" • 使用计算构造方法来构造属性,首先使用关键字 "attribute",然后以硬编码的方式指定该属性的名称 QName(限定的名称,可以包含命名空间前缀)、或者使用表达式 ("{" Expr "}") 动态地计算出该属性的名称,最后使用表达式 "{" Expr? "}" 计算出该属性的值(如果没有表达式 Expr,则属性值为空)。

  34. 属性计算构造的示例 for$nodein (<couple><husband>Tom</husband><wife>Alice</wife></couple>)/element() return element person { attribute gender {if (node-name($node) castas xs:string="husband") then"male"else"female"}, data($node) } <person gender="male">Tom</person> <person gender="female">Alice</person>

  35. ③ 其他内容的计算构造 CompTextConstructor ::= "text" "{" Expr "}" CompPIConstructor ::= "processing-instruction" (NCName | ("{" Expr "}")) "{" Expr? "}" CompCommentConstructor ::= "comment" "{" Expr "}" <result> { for$nodein (<student>WangFang</student>,<city>Beijing</city>) return element {node-name($node)} { data($node), comment {"appended-text"}, text {2+3}, processing-instruction pi-name {"some-pi"} } } </result> <result> <student>WangFang<!--appended-text-->5<?pi-name some-pi?></student> <city>Beijing<!--appended-text-->5<?pi-name some-pi?></city> </result>

  36. 条件表达式 IfExpr ::= "if" "(" TestExpr ")" "then" ExprSingle "else" ExprSingle ExprSingle ::= FLWORExpr | QuantifiedExpr | IfExpr • if-then-else.xquery some $p in //price satisfies $p > 10000 every $p in //price satisfies $p > 10000 some $s in $S satisfies $s/C exists($S[C]) every $s in $S satisfies not(C) not(some $s in $S satisfies C)

  37. 6.4灵活地使用 XQuery • XQuery 1.0 的类型系统及类型操作 • XQuery 1.0 中的类型系统与 XPath 2.0 的类型系统完全一致。 • 在 XQuery 中,增加了一些有关类型的操作,比如 typeswitch 操作符。typeswitch 操作符类似于高级程序设计语言中的 switch 语句,不同的是,它根据输入参数的类型来进行分支选择,而不是输入参数的值。 typeswitch($customer/billing-address) case$aaselement(*, USAddress) return$a/state case$aaselement(*, CanadaAddress) return$a/province case$aaselement(*, JapanAddress) return$a/prefecture defaultreturn"unknown"

  38. 在 XQuery 中编写自定义的函数 • 在 XQuery 中,除了使用内置函数之外,还允许用户声明他们自己的函数。函数声明需要指定函数的名称、参数名称及数据类型、以及返回值的数据类型。 • 函数定义的基本语法如下所示: FunctionDecl ::= "declare" "function" QName "(" ParamList? ")" ("as" SequenceType)? (EnclosedExpr | "external") ParamList ::= Param ("," Param)* Param ::= "$" QName TypeDeclaration? TypeDeclaration ::= "as" SequenceType xqueryversion"1.0"; declarefunction local:HelloWorld() as xs:string { "Hello World!" }; local:HelloWorld() xqueryversion"1.0"; declarefunction HelloWorld() as xs:string return"Hello World!" HelloWorld( )

  39. modulenamespace hello = "http://example.org/hello-function"; declarefunction hello:HelloWorld() as xs:string { "Hello World!" }; declarevariable$hello:pi as xs:double :=3.141592653589793; module1.xquery xqueryversion"1.0"; importmodulenamespace mod1 = "http://example.org/hello-function"at"module1.xquery"; <result> <function-call>{mod1:HelloWorld()}</function-call> <showVariable>{$mod1:pi}</showVariable> </result> MainQuery.xquery 模块的定义以及导入 • 模块是一组函数或变量的命名的集合。可以将一组相关的函数和变量定义在某个模块中,然后在需要的时候导入并使用。 <result> <function-call>Hello World!</function-call> <showVariable>3.14159265358979</showVariable> </result>

  40. 在 XQuery 中声明命名空间 NamespaceDecl ::= "declare" "namespace" NCName "=" URILiteral xqueryversion"1.0"; declarenamespace here ="www.example.org"; declarefunction here:HelloWorld() as xs:string { "Hello World!" }; here:HelloWorld() xqueryversion"1.0"; declarenamespace here = "http://example.org"; <here:ele> Element </here:ele> <here:ele xmlns:here="http://example.org"> Element </here:ele> xqueryversion"1.0"; declaredefaultelementnamespace"http://example.org/names"; <ele> Element </ele> <ele xmlns="http://example.org/names"> Element </ele>

  41. 使用外部 XML Schema • 在 XQuery 中,有时候我们需要使用与目标 XML 文档相关联的 XML Schema 来提供数据的类型信息(XQuery 实际上是对经过模式验证后的信息集 PSVI 进行操作)。 • 有时候目标 XML 文档并没有指定任何关联的 Schema 模式,而需要使用某些外部 XML Schema 来完成两项任务。 • 第一,对输入的 XML 数据进行验证,从而确保原始数据的有效性,并充分地利用 Schema 中的结构信息完成相关的操作; • 第二,对输出的 XML 数据进行验证,从而确保所得结果的有效性。

  42. 导入和使用 Schema • 导入了一个没有目标命名空间的 Schema 文件,指定了该文件的位置,并将缺省的元素/类型命名空间指定为空。 • Schema-Import1.xquery • Schema-Import2.xquery importschemadefaultelementnamespace""at"http://example.org/xyz.xsd";

  43. 6.5 XQuery 用例分析 • 见 XMLSPY 和教材。

More Related