引言

XQuery是一种用于查询XML数据的强大语言,类似于SQL用于查询关系数据库。要有效地学习和掌握XQuery,首先需要具备扎实的XML基础知识。本文将全面介绍学习XQuery前必须了解的XML基础知识,以及学习工具的准备和XQuery的学习路径,帮助读者系统地掌握XQuery技术。

XML基础知识

XML是什么

XML(eXtensible Markup Language,可扩展标记语言)是一种用于存储和传输数据的标记语言。XML被设计用来传输和存储数据,其焦点是数据的内容。XML不会做任何事情,它只是被设计用来结构化、存储以及传输信息。

XML的主要特点:

  • XML是一种标记语言,很类似HTML
  • XML的设计宗旨是传输数据,而非显示数据
  • XML标签没有被预定义,需要自行定义标签
  • XML被设计为具有自我描述性
  • XML是W3C的推荐标准

示例:

<?xml version="1.0" encoding="UTF-8"?> <bookstore> <book category="COOKING"> <title lang="en">Everyday Italian</title> <author>Giada De Laurentiis</author> <year>2005</year> <price>30.00</price> </book> <book category="CHILDREN"> <title lang="en">Harry Potter</title> <author>J.K. Rowling</author> <year>2005</year> <price>29.99</price> </book> </bookstore> 

XML文档结构

一个标准的XML文档包含以下几个部分:

  1. XML声明:可选,但如果存在,必须是文档的第一行

    <?xml version="1.0" encoding="UTF-8"?> 
  2. 文档类型声明(DTD):可选,用于定义文档的合法构建模块

    <!DOCTYPE note SYSTEM "Note.dtd"> 
  3. 根元素:所有XML文档必须有一个单一的根元素,它是所有其他元素的父元素

    <root> <!-- 其他元素 --> </root> 
  4. 其他元素:嵌套在根元素中的各种元素

    <child> <subchild>...</subchild> </child> 
  5. 属性:元素可以包含属性,提供有关元素的额外信息

    <element attribute="value">Content</element> 
  6. 注释:可以添加注释,提高文档的可读性

    <!-- This is a comment --> 
  7. 处理指令:可选,用于向应用程序传递信息

    <?xml-stylesheet type="text/xsl" href="style.xsl"?> 

完整的XML文档示例:

<?xml version="1.0" encoding="UTF-8"?> <!-- This is a sample XML document --> <!DOCTYPE note SYSTEM "Note.dtd"> <?xml-stylesheet type="text/xsl" href="style.xsl"?> <note> <to>Tove</to> <from>Jani</from> <heading>Reminder</heading> <body date="2023-05-15">Don't forget me this weekend!</body> </note> 

XML语法规则

XML的语法规则相对简单,但必须严格遵守:

  1. 所有XML元素都必须有关闭标签

    <p>This is a paragraph.</p> <!-- 正确 --> <p>This is a paragraph. <!-- 错误 --> 
  2. XML标签对大小写敏感

    <Message>This is different</Message> <!-- 与下面的不同 --> <message>This is different</message> <!-- 与上面的不同 --> 
  3. XML必须正确嵌套

    <b><i>This text is bold and italic</i></b> <!-- 正确 --> <b><i>This text is bold and italic</b></i> <!-- 错误 --> 
  4. XML文档必须有根元素

    <root> <child> <subchild>...</subchild> </child> </root> 
  5. XML属性值必须加引号

    <note date="2023-05-15"> <!-- 正确 --> <note date=2023-05-15> <!-- 错误 --> 
  6. 实体引用:在XML中,一些字符具有特殊意义,如果要使用这些字符,必须使用实体引用

    • &lt; 代表 <
    • &gt; 代表 >
    • & 代表 &
    • &apos; 代表 ‘
    • &quot; 代表 “

示例:

 <message>If a &lt; b &amp; b &lt; c, then a &lt; c.</message> 
  1. 在XML中,空格会被保留
     <message>Hello World</message> <!-- 空格会被保留 --> 

XML命名空间

XML命名空间(Namespace)提供了一种避免元素命名冲突的方法。由于XML文档中可以使用来自不同应用的元素,可能会出现命名冲突。命名空间通过为元素和属性提供唯一的名称来解决这个问题。

命名空间声明语法:

<element xmlns:prefix="URI"> 

其中:

  • xmlns是命名空间声明的关键字
  • prefix是命名空间的前缀(可选)
  • URI是命名空间的唯一标识符(通常是URL)

示例:

<root xmlns:f="http://www.w3schools.com/furniture" xmlns:t="http://www.w3schools.com/toys"> <f:table> <f:name>African Coffee Table</f:name> <f:width>80</f:width> <f:length>120</f:length> </f:table> <t:table> <t:name>Wooden Play Table</t:name> <t:width>60</t:width> <t:length>100</t:length> </t:table> </root> 

在上面的例子中,两个table元素来自不同的命名空间,因此它们不会冲突。

默认命名空间:

<root xmlns="http://www.w3schools.com/furniture"> <table> <name>African Coffee Table</name> <width>80</width> <length>120</length> </table> </root> 

在这个例子中,所有没有前缀的元素都属于默认命名空间。

XML Schema和DTD

DTD(Document Type Definition,文档类型定义)和XML Schema都是用于定义XML文档结构和内容的规范。它们定义了XML文档中可以包含哪些元素,这些元素之间的关系,以及每个元素可以包含什么类型的数据。

DTD

DTD是较早的XML文档定义方式,语法相对简单。

内部DTD声明:

<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE note [ <!ELEMENT note (to,from,heading,body)> <!ELEMENT to (#PCDATA)> <!ELEMENT from (#PCDATA)> <!ELEMENT heading (#PCDATA)> <!ELEMENT body (#PCDATA)> ]> <note> <to>Tove</to> <from>Jani</from> <heading>Reminder</heading> <body>Don't forget me this weekend!</body> </note> 

外部DTD声明:

<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE note SYSTEM "note.dtd"> <note> <to>Tove</to> <from>Jani</from> <heading>Reminder</heading> <body>Don't forget me this weekend!</body> </note> 

note.dtd文件内容:

<!ELEMENT note (to,from,heading,body)> <!ELEMENT to (#PCDATA)> <!ELEMENT from (#PCDATA)> <!ELEMENT heading (#PCDATA)> <!ELEMENT body (#PCDATA)> 

XML Schema

XML Schema是DTD的继任者,提供了更强大和灵活的功能。XML Schema本身也是XML文档,因此更容易理解和处理。

XML Schema示例:

<?xml version="1.0"?> <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"> <xs:element name="note"> <xs:complexType> <xs:sequence> <xs:element name="to" type="xs:string"/> <xs:element name="from" type="xs:string"/> <xs:element name="heading" type="xs:string"/> <xs:element name="body" type="xs:string"/> </xs:sequence> </xs:complexType> </xs:element> </xs:schema> 

引用XML Schema的XML文档:

<?xml version="1.0"?> <note xmlns="http://www.w3schools.com" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.w3schools.com note.xsd"> <to>Tove</to> <from>Jani</from> <heading>Reminder</heading> <body>Don't forget me this weekend!</body> </note> 

DTD与XML Schema的比较

  1. XML Schema是XML文档,而DTD有自己独特的语法
  2. XML Schema支持数据类型,而DTD不支持
  3. XML Schema是可扩展的,而DTD不是
  4. XML Schema支持命名空间,而DTD的支持有限
  5. XML Schema更强大,可以定义更复杂的文档结构

XPath基础

XPath(XML Path Language)是一种在XML文档中查找信息的语言。XPath用于在XML文档中通过元素和属性进行导航。由于XQuery构建在XPath之上,因此理解XPath对于学习XQuery至关重要。

XPath节点

在XPath中,有七种类型的节点:元素、属性、文本、命名空间、处理指令、注释以及文档(根)节点。

考虑以下XML文档:

<?xml version="1.0" encoding="UTF-8"?> <bookstore> <book category="COOKING"> <title lang="en">Everyday Italian</title> <author>Giada De Laurentiis</author> <year>2005</year> <price>30.00</price> </book> <book category="CHILDREN"> <title lang="en">Harry Potter</title> <author>J.K. Rowling</author> <year>2005</year> <price>29.99</price> </book> </bookstore> 

在这个例子中:

  • <bookstore> 是文档节点(也是根元素节点)
  • <book>, <title>, <author>, <year>, <price> 是元素节点
  • category="COOKING"lang="en" 是属性节点
  • “Everyday Italian”, “Giada De Laurentiis” 等是文本节点

XPath语法

XPath使用路径表达式来选取XML文档中的节点或节点集。这些路径表达式看起来很像计算机文件系统中的路径。

最常用的路径表达式:

表达式描述
nodename选取此节点的所有子节点
/从根节点选取
//从匹配选择的当前节点选择文档中的节点,而不考虑它们的位置
.选取当前节点
..选取当前节点的父节点
@选取属性

示例(基于上面的XML文档):

路径表达式结果
bookstore选取 bookstore 元素的所有子节点
/bookstore选取根元素 bookstore
bookstore/book选取属于 bookstore 的子元素的所有 book 元素
//book选取所有 book 子元素,而不管它们在文档中的位置
bookstore//book选择属于 bookstore 元素的后代的所有 book 元素,而不管它们位于 bookstore 之下的什么位置
//@lang选取名为 lang 的所有属性

谓语(Predicates)

谓语用来查找某个特定的节点或者包含某个指定的值的节点,被嵌在方括号中。

示例:

路径表达式结果
/bookstore/book[1]选取属于 bookstore 子元素的第一个 book 元素
/bookstore/book[last()]选取属于 bookstore 子元素的最后一个 book 元素
/bookstore/book[last()-1]选取属于 bookstore 子元素的倒数第二个 book 元素
/bookstore/book[position()]选取最前面的两个属于 bookstore 元素的子元素的 book 元素
//title[@lang]选取所有拥有名为 lang 的属性的 title 元素
//title[@lang=‘en’]选取所有 title 元素,且这些元素拥有值为 en 的 lang 属性
/bookstore/book[price>35.00]选取 bookstore 元素的所有 book 元素,且其中的 price 元素的值须大于 35.00
/bookstore/book[price>35.00]/title选取 bookstore 元素中的 book 元素的所有 title 元素,且其中的 price 元素的值须大于 35.00

XPath通配符

通配符描述
*匹配任何元素节点
@*匹配任何属性节点
node()匹配任何类型的节点

示例:

路径表达式结果
/bookstore/*选取 bookstore 元素的所有子元素
//*选取文档中的所有元素
//title[@*]选取所有带有属性的 title 元素

XPath轴

轴定义了相对于当前节点的节点集。

轴名称结果
ancestor选取当前节点的所有先辈(父、祖父等)
ancestor-or-self选取当前节点的所有先辈以及当前节点本身
attribute选取当前节点的所有属性
child选取当前节点的所有子元素
descendant选取当前节点的所有后代元素(子、孙等)
descendant-or-self选取当前节点的所有后代元素以及当前节点本身
following选取文档中当前节点的结束标签之后的所有节点
namespace选取当前节点的所有命名空间节点
parent选取当前节点的父节点
preceding选取文档中当前节点的开始标签之前的所有节点
preceding-sibling选取当前节点之前的所有同级节点
self选取当前节点

XPath运算符

运算符描述实例返回值
|计算两个节点集//book | //cd返回所有拥有 book 和 cd 元素的节点集
+加法6 + 410
-减法6 - 42
*乘法6 * 424
div除法8 div 42
=等于price=9.80如果 price 是 9.80,则返回 true。如果 price 是 9.90,则返回 false。
!=不等于price!=9.80如果 price 是 9.90,则返回 true。如果 price 是 9.80,则返回 false。
<小于price<9.80如果 price 是 9.00,则返回 true。如果 price 是 9.90,则返回 false。
<=小于或等于price<=9.80如果 price 是 9.00,则返回 true。如果 price 是 9.90,则返回 false。
>大于price>9.80如果 price 是 9.90,则返回 true。如果 price 是 9.80,则返回 false。
>=大于或等于price>=9.80如果 price 是 9.90,则返回 true。如果 price 是 9.70,则返回 false。
orprice=9.80 or price=9.70如果 price 是 9.80,则返回 true。如果 price 是 9.50,则返回 false。
andprice>9.00 and price<9.90如果 price 是 9.80,则返回 true。如果 price 是 8.50,则返回 false。
mod计算除法的余数5 mod 21

XQuery概述

XQuery的定义和用途

XQuery是一种用于查询XML数据的查询语言,由W3C开发。XQuery被设计用来查询、提取和操作XML文档中的数据。XQuery对于XML数据库和包含XML数据的文档处理系统特别有用。

XQuery的主要用途:

  1. 从XML文档中提取信息
  2. 转换XML数据
  3. 生成新的XML文档
  4. 查询XML数据库
  5. 与Web服务集成

XQuery的特点:

  • 强大的查询能力:可以查询XML文档中的任何部分
  • 灵活性:可以处理各种XML数据结构
  • 可扩展性:支持用户定义的函数
  • 与XPath兼容:XQuery构建在XPath之上
  • 类型安全:支持数据类型检查

XQuery与XPath的关系

XQuery构建在XPath之上,XPath是XQuery的一个子集。XPath提供了在XML文档中导航和选择节点的语法,而XQuery则在此基础上增加了更多的功能,如FLWOR表达式、条件表达式、量词表达式等。

简单来说:

  • XPath用于在XML文档中定位节点
  • XQuery用于查询、转换和生成XML数据

XQuery使用XPath表达式来选择XML文档中的节点,然后对这些节点进行进一步的处理。

XQuery与其他查询语言的比较

  1. XQuery与SQL的比较:

    • SQL用于查询关系数据库,XQuery用于查询XML数据
    • SQL基于表格模型,XQuery基于树形模型
    • SQL使用SELECT语句,XQuery使用FLWOR表达式
    • XQuery比SQL更灵活,可以处理半结构化数据
  2. XQuery与XSLT的比较:

    • XSLT主要用于转换XML文档,XQuery主要用于查询XML数据
    • XSLT基于模板规则,XQuery基于FLWOR表达式
    • XQuery比XSLT更接近传统编程语言
    • XQuery通常比XSLT更简洁、更易读
  3. XQuery与Java/C#等编程语言的比较:

    • XQuery是声明式语言,Java/C#是命令式语言
    • XQuery专门用于处理XML数据,Java/C#是通用编程语言
    • XQuery比Java/C#更简洁,但功能相对有限
    • XQuery可以嵌入到Java/C#程序中使用

学习工具准备

开发环境设置

为了学习和使用XQuery,需要设置适当的开发环境。以下是一些建议的工具和环境:

  1. 文本编辑器:

    • Notepad++:轻量级文本编辑器,支持XML和XQuery语法高亮
    • Sublime Text:强大的文本编辑器,支持多种插件
    • Visual Studio Code:微软开发的免费编辑器,支持XQuery插件
    • Oxygen XML Editor:专业的XML编辑器,提供全面的XML和XQuery支持
  2. XQuery处理器:

    • BaseX:轻量级XML数据库和XQuery处理器
    • eXist-db:开源XML数据库
    • Saxon:高性能XSLT和XQuery处理器
    • MarkLogic:企业级NoSQL数据库,支持XQuery
  3. 集成开发环境(IDE):

    • Oxygen XML Editor:提供全面的XML和XQuery开发支持
    • Stylus Studio:专业的XML IDE,支持XQuery开发
    • Eclipse:通过插件支持XQuery开发

XQuery处理器和工具推荐

  1. BaseX:

    • 特点:轻量级、开源、跨平台
    • 优点:易于安装和使用,提供图形界面和命令行界面
    • 适用场景:学习和开发小型XQuery应用
    • 下载地址:http://basex.org/
  2. eXist-db:

    • 特点:开源XML数据库,支持XQuery
    • 优点:功能强大,支持Web界面
    • 适用场景:开发基于XML的Web应用
    • 下载地址:http://exist-db.org/
  3. Saxon:

    • 特点:高性能XSLT和XQuery处理器
    • 优点:符合W3C标准,支持XQuery 3.1
    • 适用场景:企业级应用开发
    • 下载地址:http://www.saxonica.com/
  4. MarkLogic:

    • 特点:企业级NoSQL数据库,支持XQuery
    • 优点:高性能,可扩展性好
    • 适用场景:大型企业应用
    • 下载地址:https://www.marklogic.com/
  5. Oxygen XML Editor:

    • 特点:专业的XML编辑器
    • 优点:提供全面的XML和XQuery支持,包括调试、验证等功能
    • 适用场景:专业XML和XQuery开发
    • 下载地址:https://www.oxygenxml.com/

在线资源和文档

  1. W3C XQuery规范:

    • 网址:https://www.w3.org/TR/xquery-31/
    • 描述:XQuery的官方规范文档
  2. XQuery教程:

    • W3Schools XQuery教程:https://www.w3schools.com/xml/xquery_intro.asp
    • 描述:提供基础的XQuery概念和示例
  3. XQuery函数参考:

    • W3Schools XQuery函数参考:https://www.w3schools.com/xml/xquery_functions.asp
    • 描述:列出XQuery内置函数及其用法
  4. Stack Overflow:

    • 网址:https://stackoverflow.com/questions/tagged/xquery
    • 描述:XQuery相关的问答社区
  5. XQuery Wikibook:

    • 网址:https://en.wikibooks.org/wiki/XQuery
    • 描述:免费的XQuery在线书籍
  6. Priscilla Walmsley的XQuery书籍:

    • 书名:《XQuery》
    • 描述:由XQuery专家编写的权威指南

XQuery学习路径

初级阶段:基础语法和简单查询

在初级阶段,需要掌握XQuery的基础语法和简单的查询操作。

  1. XQuery基础语法:

    • XQuery注释:(: 这是一个注释 :)
    • XQuery变量:$variable
    • XQuery字符串:"字符串"'字符串'
    • XQuery序列:(1, 2, 3)
  2. 简单查询:

    • 直接返回XML文档:

      doc("books.xml")/bookstore/book/title 
    • 使用FLWOR表达式:

      for $x in doc("books.xml")/bookstore/book where $x/price > 30 return $x/title 
  3. 条件表达式:

    if (doc("books.xml")/bookstore/book[1]/price > 30) then "Expensive" else "Affordable" 
  4. 学习资源:

    • W3Schools XQuery教程
    • XQuery Wikibook的入门章节
    • BaseX或eXist-db的官方教程

中级阶段:复杂查询和函数使用

在掌握基础语法后,可以进入中级阶段,学习更复杂的查询和函数使用。

  1. 复杂FLWOR表达式:

    • 使用let子句:

      for $x in doc("books.xml")/bookstore/book let $y := $x/price * 0.8 <!-- 20% discount --> where $x/price > 30 return <book>{$x/title, <discountedPrice>{$y}</discountedPrice>}</book> 
    • 使用order by子句:

      for $x in doc("books.xml")/bookstore/book order by $x/price descending return $x/title 
    • 使用group by子句(XQuery 3.0+):

      for $x in doc("books.xml")/bookstore/book group by $category := $x/@category return <category name="{$category}">{$x/title}</category> 
  2. 函数使用:

    • 内置函数:

      fn:concat("Hello", " ", "World") <!-- 返回 "Hello World" --> fn:substring("Hello World", 1, 5) <!-- 返回 "Hello" --> fn:count(doc("books.xml")/bookstore/book) <!-- 返回书籍数量 --> 
    • 用户定义函数: “`xquery declare function local:discount((price as xs:decimal, )rate as xs:decimal) as xs:decimal { (price * (1 - )rate) };

    for (x in doc("books.xml")/bookstore/book return <book>{)x/title, {local:discount($x/price, 0.2)}} “`

  3. 模块和命名空间: “`xquery import module namespace util = “http://example.com/util” at “util.xq”;

util:process-data(doc(“books.xml”)) “`

  1. 学习资源:
    • Priscilla Walmsley的《XQuery》书籍
    • W3C XQuery规范的相关章节
    • XQuery函数参考文档

高级阶段:高级特性和实际应用

在高级阶段,可以学习XQuery的高级特性和实际应用。

  1. 高级特性:

    • 更新表达式(XQuery Update Facility):

      insert node <book category="WEB"> <title lang="en">Learning XML</title> <author>Erik T. Ray</author> <year>2003</year> <price>39.95</price> </book> into doc("books.xml")/bookstore 
    • 全文本搜索:

      for $x in doc("books.xml")/bookstore/book where ft:contains($x/title, "Italian") return $x 
    • 高级序列操作:

      let $sequence := (1, 2, 3, 4, 5) return ( sum($sequence), <!-- 返回 15 --> avg($sequence), <!-- 返回 3 --> max($sequence), <!-- 返回 5 --> min($sequence) <!-- 返回 1 --> ) 
  2. 实际应用:

    • Web应用开发: “`xquery xquery version “3.1”;

    declare namespace rest = “http://exquery.org/ns/restxq”;

    declare %rest:GET %rest:path(“/books/{(category}") function local:get-books-by-category()category as xs:string) { let (books := doc("books.xml")/bookstore/book[@category = )category] return {$books} };

     - 数据转换: ```xquery xquery version "3.1"; let $xml := doc("books.xml")/bookstore return <html> <head> <title>Book List</title> </head> <body> <h1>Book List</h1> <table> <tr> <th>Title</th> <th>Author</th> <th>Price</th> </tr> { for $book in $xml/book return <tr> <td>{$book/title/text()}</td> <td>{$book/author/text()}</td> <td>{$book/price/text()}</td> </tr> } </table> </body> </html> 
    • 与其他技术集成:
      • XQuery与RESTful服务
      • XQuery与JSON处理(XQuery 3.1+)
      • XQuery与数据库集成
  3. 学习资源:

    • W3C XQuery 3.1规范
    • XQuery Update Facility规范
    • 高级XQuery书籍和论文
    • 开源项目案例研究

实践项目建议

为了巩固XQuery知识,建议完成以下实践项目:

  1. XML数据查询项目:

    • 目标:查询和分析XML数据
    • 要求:创建一个XML文档,包含书籍、作者、出版社等信息,然后使用XQuery查询这些数据
    • 示例查询:
      • 查找所有价格超过30美元的书籍
      • 按作者分组显示书籍
      • 计算每个类别的平均价格
  2. XML数据转换项目:

    • 目标:将XML数据转换为其他格式
    • 要求:使用XQuery将XML数据转换为HTML、JSON或其他XML格式
    • 示例转换:
      • 将书籍列表转换为HTML表格
      • 将书籍信息转换为JSON格式
      • 生成书籍目录的RSS订阅源
  3. Web应用开发项目:

    • 目标:开发基于XQuery的Web应用
    • 要求:使用支持XQuery的数据库(如BaseX或eXist-db)开发一个简单的Web应用
    • 示例应用:
      • 在线图书目录
      • 简单的博客系统
      • 文档管理系统
  4. 数据集成项目:

    • 目标:集成多个XML数据源
    • 要求:使用XQuery查询和合并多个XML文档
    • 示例集成:
      • 合并来自不同供应商的产品目录
      • 整合来自不同系统的用户数据
      • 生成综合报告

总结和进阶学习建议

总结

XQuery是一种强大的XML查询语言,可以用于查询、转换和生成XML数据。学习XQuery需要掌握以下关键点:

  1. 扎实的XML基础知识:包括XML文档结构、语法规则、命名空间、Schema/DTD等
  2. 熟练的XPath技能:XPath是XQuery的基础,需要熟练掌握XPath的各种表达式和函数
  3. XQuery语法和特性:包括FLWOR表达式、条件表达式、函数等
  4. 实践经验:通过实际项目巩固所学知识

进阶学习建议

  1. 深入学习XQuery标准:

    • 阅读W3C XQuery规范
    • 了解XQuery的最新发展,如XQuery 3.1的新特性
  2. 探索相关技术:

    • XQuery Update Facility:学习如何使用XQuery更新XML数据
    • XSLT:比较XQuery和XSLT,了解各自的优缺点
    • XML数据库:深入了解支持XQuery的数据库系统
  3. 参与社区:

    • 加入XQuery相关的邮件列表和论坛
    • 参与开源项目,贡献代码
    • 参加相关的会议和研讨会
  4. 持续实践:

    • 解决实际问题
    • 参与编程挑战
    • 开发个人项目

通过系统学习和持续实践,可以掌握XQuery技术,并应用于实际项目中。XQuery作为一种专业的XML查询语言,在处理XML数据方面具有独特的优势,掌握这项技术将为你的职业发展带来新的机会。