[XML]学习笔记(七)XPath&XQuery

XPath是在XML文档中查找信息的语言,可以在XML文档中对元素和属性进行遍历。XQuery和XPointer都是建立在XPath之上的。注意:只给出XPath,也可以返回该XPath下的所有节点的集合。

一、 XPath简介:

a) 使用路径表达式来选取XML文档中的节点或节点集,与文件系统的路径十分相似;

b) 含有100多个内建函数,可用于字符串值、数值、时间和日期比较等;

c) 属于XSLT标准中的主要元素;

d) 属于W3C标准。

二、 XPath节点:共七种,XML文档被当作节点树对待,树根称为文档节点/根节点。

<bookstore>
<book category="CHILDREN">
  <title lang="en">Harry Potter</title>
  <author>J K. Rowling</author>
  <year>2005</year>
  <price>29.99</price>
</book>
</bookstore>

a) 元素:如<author>J K. Rowling</author>;

b) 属性:如lang="en";

c) 文本;

d) 命名空间;

e) 处理指令;

f) 注释;

g) 根节点。

三、 XPath节点关系:

a) Parent:父节点;

b) Children:子节点;

c) Sibling:同胞节点;

d) Ancestor:先辈节点;

e) Descendant:后代节点;

f) Preceding:当前节点的开始标签之前的所有节点;

g) Following:当前节点的开始标签之后的所有节点。

四、 基本值/原子值(Atomic value):无父节点或无子节点的节点,如元素的值J K. Rowling,属性的值"en"。

五、 项目:即基本值或节点。

六、 XPath语法:每个XPath表达式由若干个step组成,除了最后一个step每个都会返回一个set节点,而最后一个step可以返回number、boolean、字符串或node集合。

a) 选取节点:

i. nodename:选取当前节点的所有子节点,如bookstore,选取bookstore元素的所有子节点。

ii. /:从根节点开始选取。

1. 如/bookstore,选取bookstore作为根元素。

注:如果路径起始于/,则此路径始终代表到对应元素的绝对路径?

2. 如bookstore/book,选取bookstore子元素中的所有book元素。

iii. //:从匹配选择的当前节点选择文档中的节点,不考虑其位置。

1. 如//book,表示选取所有的book子元素,不考虑其在文档中的位置。

2. 如bookstore//book,选择bookstore后代中的所有book元素。

iv. .:选取当前节点,相当于self::。

v. ..:选取当前结点的父节点,相当于parent::。

vi. @:选取属性。如//@lang,表示选取所有lang属性。

b) 谓词(Predicates):嵌在方括号中,用于查找某个特定的/包含某个特定值得节点。

i. /bookstore/book[1]:选取bookstore子元素中的第一个book元素;

/bookstore/book[last()]:选取bookstore子元素中的最后一个book元素;

/bookstore/book[position()<3]:选取bookstore子元素中的前两个book元素;

ii. //title[@lang]:选取所有含有lang属性的title元素;

//title[@lang=’eng’]:选取所有lang属性为eng的title元素。

iii. /bookstore/book[price>35.00]/title:选取bookstore下price高于35.00的book的title元素。

iv. /book/price/text():取book的子元素price的文本内容。

v. count()怎么用?如何计数papar下的所有title?

c) 通配符:*匹配任何节点元素;

i. 如/bookstore/*,表示选取bookstore元素的所有子元素。

ii. 如//*,表示选取文档中的所有元素。

iii. 如//title[@*],表示选取所有带属性的title元素。

d) 选取多条路径:|

i. //book/title | //book/price:选出所有book元素的title和price?选取 book 元素的所有 title 和 price 元素?

ii. //title | //price:选出文档中所有title元素和price元素。

iii. /bookstore/book/title | //price:选出bookstore中子元素为book的所有title子元素和所有文档中的所有price元素。

七、 XPath轴(Axes):用于定义相对于当前节点的节点集。位置路径可以是绝对的(以/开始)也可以是相对的(以元素/节点开始),每个/分隔一个step。

a) Step:语法——axisName::nodeTest[predicate]

i. axis:定义所选节点与当前节点之间的树状关系。

ii. nodeTest:识别轴内部的节点。

iii. predicate:0个或多个,用于筛选所选节点集。

例:

i. child::book:选取所有属于当前节点的子元素的book节点。

ii. attribute::lang:选取当前节点的 lang 属性。

iii. child::*:选取当前节点的所有子元素。

iv. attribute::*:选取当前节点的所有属性。

v. child::text():选取当前节点的所有文本子节点。

vi. child::node():选取当前节点的所有子节点。

vii. descendant::book:选取当前节点的所有book后代。

viii. ancestor::book:选择当前节点的所有book先辈。

ix. ancestor-or-self::book:选取当前节点的所有book先辈以及当前节点(如果此节点是 book 节点)

x. child::*/child::price:选取当前节点的所有 price 孙节点。

注:child::相当于空轴名,如/root/paper=/child::root/child::paper

绝对路径:

相对路径:

XQuery:“XQuery与XML的关系好比SQL与数据库的关系”,它被设计用来查询XML数据,建立在XPath表达式之上,被所有主要的数据库引擎支持(Oracle,Microsoft,IBM等)。

考虑books.xml:

<?xml version="1.0" encoding="ISO-8859-1"?>

<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>

<book category="WEB">
  <title lang="en">XQuery Kick Start</title>
  <author>James McGovern</author>
  <author>Per Bothner</author>
  <author>Kurt Cagle</author>
  <author>James Linn</author>
  <author>Vaidyanathan Nagarajan</author>
  <year>2003</year>
  <price>49.99</price>
</book>

<book category="WEB">
  <title lang="en">Learning XML</title>
  <author>Erik T. Ray</author>
  <year>2003</year>
  <price>39.95</price>
</book>

</bookstore>

一个比较简单的例子:

doc("books.xml")/bookstore/book[price>35]/count(author)

查询结果:5 1

即所有价格大于35的书的作者数量。

一、 XQuery基本语法规则:

a) 对大小写敏感;

b) 元素、属性及变量必须是合法的XML名称;

c) 字符串可使用单引号或双引号;

d) 变量由$name定义;

e) 注释格式:(:注释内容:)。

二、 XQuery语法:

a) 条件表达式:If-Then-Else,其中If和Else是必须的,Then可有可无。

如:

for $x in doc("books.xml")/bookstore/book
return if ($x/@category="CHILDREN")
	then <child>{data($x/title)}</child>
	else <adult>{data($x/title)}</adult>

查询结果如下:

<adult>Everyday Italian</adult>
<child>Harry Potter</child>
<adult>Learning XML</adult>
<adult>XQuery Kick Start</adult>

b) 比较操作:

i. 通用比较:=, !=, <, <=, >, >=。

如:$bookstore//book/@q > 10,如果属性q的值大于10,则表达式的返回值为true。

ii. 值比较:eq, ne, lt, le, gt, ge。

如:如果返回的属性q有且只有1个且值大于10,则返回true;如果返回的属性q有多个,则发生错误。

三、 XQuery高级语法:

a) 添加元素和属性:

i. 添加元素和文本:

<ul>
{
for $x in doc("books.xml")/bookstore/book
order by $x/title
return <li>{data($x/title)}. Category: {data($x/@category)}</li>
}
</ul>

查询结果:

<ul>
<li>Everyday Italian. Category: COOKING</li>
<li>Harry Potter. Category: CHILDREN</li>
<li>Learning XML. Category: WEB</li>
<li>XQuery Kick Start. Category: WEB</li>
</ul>

ii. 添加属性:使用class添加属性

<ul>
{
for $x in doc("books.xml")/bookstore/book
order by $x/title
return <li class="{data($x/@category)}">{data($x/title)}</li>
}
</ul>

查询结果:

<ul>
<li class="COOKING">Everyday Italian</li>
<li class="CHILDREN">Harry Potter</li>
<li class="WEB">Learning XML</li>
<li class="WEB">XQuery Kick Start</li>
</ul>

b) FLWOR表达式:FLWOR即For, Let, Where, Order by, Return。

上面的例子可表示为:

for $x in doc("books.xml")/bookstore/book
where $x/price>35
return $x/count(author)

i. 加标签:

xquery version "1.0";
<ul>
{
for $x in doc("books.xml")/bookstore/book
where $x/price>35
return <li>{$x/count(author)}</li>
}
</ul>

查询结果:

<ul>
<li>5</li>
<li>1</li>
</ul>

ii. data()去除元素标签,只显示内部数据:

<ul>
{
for $x in doc("books.xml")/bookstore/book/title
order by $x
return <li>{data($x)}</li>
}
</ul>

查询结果:

<ul>
<li>Everyday Italian</li>
<li>Harry Potter</li>
<li>Learning XML</li>
<li>XQuery Kick Start</li>
</ul>

iii. for语句:将变量$x绑定到in表达式中返回的每个项目中。in表达式中使用关键字to可限定循环次数,使用关键字at可计算循环次数。对于含有多个in表达式的,使用逗号分隔它们,循环次数为多个in表达式可取项目的组合数。

如:

at关键字:

for $x at $i in doc("books.xml")/bookstore/book/title
return <book>{$i}. {data($x)}</book>

查询结果:变量i记录了循环的次数

<book>1. Everyday Italian</book>
<book>2. Harry Potter</book>
<book>3. XQuery Kick Start</book>
<book>4. Learning XML</book>

多循环变量:

for $x in (10,20), $y in (100,200)
return <test>x={$x} and y={$y}</test>

查询结果:

<test>x=10 and y=100</test>
<test>x=10 and y=200</test>
<test>x=20 and y=100</test>
<test>x=20 and y=200</test>

循环嵌套:

for $x1 in doc("books.xml")/bookstore
return for $x2 in $x1/book
return $x2/price

等价于:

for $x2 in (for $x1 in doc("books.xml")/bookstore
return $x1/book)
return $x2/price

查询结果:

<price>30.00</price>
<price>29.99</price>
<price>49.99</price>
<price>39.95</price>

iv. let语句:用于变量分配,迭代产生中间结果,与for的区别:for会产生多个绑定,而let只产生一次绑定。而且let中没有at关键字。

如:

let $x :=doc("books.xml")/bookstore/book/title
return <book>{data($x)}</book>

查询结果:

<book>
Everyday ItalianHarry
PotterXQuery
Kick
StartLearning XML
</book>

v. where语句:用于过滤绑定的结果,后面常跟条件表达式。

for $x in doc("books.xml")/bookstore/book
where $x/price>30 and $x/price<100
return $x

查询结果:

<book category="WEB">
<title lang="en">XQuery Kick Start</title>
<author>James McGovern</author>
<author>Per Bothner</author>
<author>Kurt Cagle</author>
<author>James Linn</author>
<author>Vaidyanathan Nagarajan</author>
<year>2003</year>
<price>49.99</price>
</book>
<book category="WEB">
<title lang="en">Learning XML</title>
<author>Erik T. Ray</author>
<year>2003</year>
<price>39.95</price>
</book>

vi. order by语句:用于将结果排序,可以通过order_spec=ascending/descending来指定升序(默认)还是降序。注意:order by默认按指定元素升序排列,但不含order by的查询并不表示将按升序排列。

如:

for $x in doc("books.xml")/bookstore/book
where $x/price>30 and $x/price<100
order by $x/price descending
return $x

vii. return语句:规定要返回的内容。

c) XQuery用户定义函数:

i. 语法:

declare function 前缀:函数名($参数 as 数据类型)

as 返回的数据类型

{

(: ...函数代码... :)

};

如下面的例子中:

declare function local:minPrice(
  $price as xs:decimal)
  as xs:decimal
{
let $disc :=($price) div 100
return ($price - $disc)
};
for $x in doc("books.xml")/bookstore/book
return <minPrice>{local:minPrice($x/price)}</minPrice>

查询结果如下:

<minPrice>29.7</minPrice>
<minPrice>29.6901</minPrice>
<minPrice>49.4901</minPrice>
<minPrice>39.5505</minPrice>

四、 利用XQuery将XML转化成HTML的例子:

源XML文档即books.xml,目标html的显示效果为:

目标html为:

<html>
	<head><title>Book List</title></head>
	<body>
		<h1>Book List</h1>
		<table border="1" cols="3" width="100%">
			<tbody>
			<tr>
				<td><year>2005</year></td>
				<td><author>Giada De Laurentiis</author></td>
				<td><price>30.00</price></td>
			</tr>
			<tr>
				<td><year>2005</year></td>
				<td><author>J K. Rowling</author></td>
				<td><price>29.99</price></td>
			</tr>
			<tr>
				<td><year>2003</year></td>
				<td><author>James McGovern</author>
					<author>Per Bothner</author>
					<author>Kurt Cagle</author>
					<author>James Linn</author>
					<author>Vaidyanathan Nagarajan</author>
				</td>
				<td><price>49.99</price></td>
			</tr>
			<tr>
				<td><year>2003</year></td>
				<td><author>Erik T. Ray</author></td>
				<td><price>39.95</price></td>
			</tr>
			</tbody>
		</table>
	</body>
</html>

转换的XQuery为:

xquery version "1.0";

<html>
	<head><title>Book List</title></head>
	<body>
		<h1>Book List</h1>
		<table border="1" cols="3" width="100%">
			<tbody>
			{
			for $x in doc("books.xml")/bookstore/book
				return <tr>
					<td>{$x/year}</td>
					<td>{$x/author}</td>
					<td>{$x/price}</td>
				</tr>
			}
			</tbody>
		</table>
	</body>
</html>

五、 利用XQuery实现XML之间的转换:

原XML文档:

<company>
	<div no="7a">
		<dept no="42">
			<emp no="123456" name="Whoptimone, Ida"/>
			<emp no="654321" name="Tirebiter, George"/>
		</dept>
		<dept no="51">
			<emp no="832953" name="Danger, Nick"/>
		</dept>
	</div>
	<div no="2b">
		<dept no="57">
			<emp no="283412" name="Boss, Yuda"/>
		</dept>
	</div>
</company>

目标XML文档:

转换XQuery文档:

(:<company>
	for $div in doc("company.xml")/company/div
		return for $dept in $div/dept
			return for $emp in $dept/emp
				return <employee id="{data($emp/@no)}">
					<name>{data($emp/@name)}</name>
					<division>{data($div/@no)}</division>
					<department>{data($dept/@no)}</department>
				</employee>
</company>:)

<company>
{
for $emp in doc("company.xml")//emp
	 return <employee id="{data($emp/@no)}">
	            <name>{data($emp/@name)}</name>
	            <division>{data($emp /../../@no)}</division>
	            <department>{data($emp /../@no)}</department>
             </employee>
}
</company>

时间: 2024-10-10 06:58:22

[XML]学习笔记(七)XPath&XQuery的相关文章

xml学习笔记 6.XQuery

XQuery xml query 是一种专门用于xml半结构化数据的查询语言,是W3C的推荐的标准语言. XQuery是有一些SQL专家制定的,基本语法与sql语句非常相似.比xslt更加简单. FLOWR语句与select语句相对应,完成对xml数据的查询,筛选和排序.FLOWR是指FOR,LET,WHERE,ORDERBY,RETURN五种语句.其中可以使用XPATH路径表达式以及xpath中的内置函数,各种自定义的函数,和命名空间. for子句: for $b in doc("bib-de

XML学习笔记(五):使用 jdom和dom4j 解析XML

XML解析的详细分析与jaxp解析XML详见:XML学习笔记(四):使用 DOM和SAX 解析XML 一.JDom 1.创建XML文件: 1)Document类即代表整个XML文档,把生成的 Document 利用 XMLOutputter 类输出即可. 2)映射关系:元素:Element:属性:Attribute:注解:Comment:文本信息:Text: 3)注意:addContent()是追加,setContent()会覆盖. /** * 创建XML * * @throws IOExcep

第十七篇:博采众长--初探WDDM驱动学习笔记(七)

基于WDDM驱动的DirectX视频加速重定向框架设计与实现 现在的研究生的论文, 真正质量高的, 少之又少, 开题开得特别大, 动不动就要搞个大课题, 从绪论开始到真正自己所做的内容之间, 是东拼西凑地抄概念, 抄公式, 达到字数篇幅的要求, 而自己正真做了什么, 有哪些实际感受, 做出的内容, 相比前面的东拼西凑就几点内容, 之后就草草结束, 步入感谢的段落. 原因不光只有学生自己, 所谓的读研, 如果没有一个环境, 学生有再大的愿望, 再强的毅力, 到头来也只是空无奈. 有些导师要写书,

马哥学习笔记七——LAMP编译安装之MYSQL

1.准备数据存放的文件系统 新建一个逻辑卷,并将其挂载至特定目录即可.这里不再给出过程. 这里假设其逻辑卷的挂载目录为/mydata,而后需要创建/mydata/data目录做为mysql数据的存放目录. 2.新建用户以安全方式运行进程: # groupadd -r mysql # useradd -g mysql -r -s /sbin/nologin -M -d /mydata/data mysql # chown -R mysql:mysql /mydata/data 3.安装并初始化my

Lua学习笔记(七):迭代器与泛型for

1.迭代器与闭包 迭代器是一种支持指针类型的结构,它可以遍历集合的每一个元素.在Lua中我们常常使用函数来描述迭代器,每次调用该函数就返回集合的下一个元素. 迭代器需要保留上一次成功调用的状态和下一次成功调用的状态,也就是他知道来自于哪里和将要前往哪里.闭包提供的机制可以很容易实现这个任务.记住:闭包是一个内部函数,它可以访问一个或者多个外部函数的外部局部变量.每次闭包的成功调用后这些外部局部变量都保存他们的值(状态).当然如果要创建一个闭包必须要创建其外部局部变量.所以一个典型的闭包的结构包含

python学习笔记七:条件&循环语句

1.print/import更多信息 print打印多个表达式,使用逗号隔开 >>> print 'Age:',42 Age: 42   #注意个结果之间有一个空格符 import:从模块导入函数 import 模块 from 模块 import 函数 from 模块 import * 如果两个模块都有open函数的时候, 1)使用下面方法使用: module1.open()... module2.open()... 2)语句末尾增加as子句 >>> import ma

swift学习笔记(七)自动引用计数

与Object-c一样,swift使用自动引用计数来跟踪并管理应用使用的内存.当实例不再被使用时,及retainCount=0时,会自动释放是理所占用的内存空间. 注:引用计数仅适用于类的实例,因为struct和enumeration属于值类型,也就不牵涉引用,所以其存储和管理方式并不是引用计数. 当一个实例被初始化时,系统会自动分配一定的内存空间,用于管理属性和方法.当实例对象不再被使用时,其内存空间被收回. swift中的引用类型分为三种,即Strong强引用,weak弱引用和无主引用unw

Swift学习笔记七:闭包

闭包可以 捕获 和存储其所在上下文中任意常量和变量的引用. Swift 会为您管理在 捕获 过程中涉及到的内存操作. 在 函数 章节中介绍的全局和嵌套函数实际上也是特殊的闭包,闭包采取如下三种形式之一: 1. 全局函数是一个有名字但不会捕获任何值的闭包 2. 嵌套函数是一个有名字并可以捕获其封闭函数域内值的闭包 3. 闭包表达式是一个可以捕获其上下文中变量或常量值的没有名字的闭包 一.闭包表达式 闭包函数类似于Objective-C中的block.下面我们用事实说话: let counts =

Linux System Programming 学习笔记(七) 线程

1. Threading is the creation and management of multiple units of execution within a single process 二进制文件是驻留在存储介质上,已被编译成操作系统可以使用,准备执行但没有正运行的休眠程序 进程是操作系统对 正在执行中的二进制文件的抽象:已加载的二进制.虚拟内存.内核资源 线程是进程内的执行单元 processes are running binaries, threads are the smal

xml学习笔记(1)

xml 学习笔记 XML : W3C 提供的可拓展的HTMl标签 作用 : 存储,配置 数据存储在XMl中,写好XML文件后要用程序去读取其中的数据,而读取程序的过程叫做解析. xml 的解析方式分为两种: dom (Document Objecct Model 文档对象模型) W3C组织推荐的解析模式 Sax (Simple API for Xml )是xml社区事实上的标准 ,几乎所有的XML解析器都支持它 XML 解析器: Crimson(sun ) Xerces(IBM) Aelfred