<?xml version="1.0" encoding="UTF-8"?>
<!-- edited with XMLSpy v2008 rel. 2 sp2 (http://www.altova.com) by Administrator -->
<?xml-stylesheet type="text/xsl" href="messages.xsl"?>
<messages>
<message id="1">
<sender>gukaitong@gmail.com</sender>
<to>anonymous@gmail.com
<group name="IT">
<address>111@gmail.com</address>
<address>222@gmail.com</address>
<address>aaa@gmail.com</address>
<address>bbb@gmail.com</address>
<address>ccc@gmail.com</address>
</group>
</to>
<subject>This is a sample</subject>
<datetime date="2008-12-11" time="12:00:00" formatted="12/11/2008 12:00AM">2008-12-11T12:00:00Z</datetime>
<body>
Are you interested in?
<attachments>
<attachment id="1">
<message id="0">
<sender>anonymous@gmail.com</sender>
<to>gukaitong@gmail.com</to>
<body>
We strongly recommend the following books
<books xmlns:amazon="http://www.amazon.com/books/schema">
<amazon:book>
<name>Professional C# 2008 </name>
<country>USA</country>
<price>37.79</price>
<year>2007</year>
</amazon:book>
<amazon:book>
<name>Microsoft Visual C# 2008 Step by Step </name>
<country>USA</country>
<price>26.39 </price>
<year>2008</year>
</amazon:book>
<amazon:book>
<name>C# in Depth</name>
<country>USA</country>
<price>29.69 </price>
<year>2006</year>
</amazon:book>
<amazon:book>
<name>Thinking in Java</name>
<country>USA</country>
<price>23.69 </price>
<year>2004</year>
</amazon:book>
</books>
</body>
</message>
</attachment>
</attachments>
</body>
</message>
<message id="2">
<sender>333@gmail.com</sender>
<to>444@gmail.com</to>
<subject>No title</subject>
<body/>
</message>
</messages>

XPath简介

XPath是W3C的一个标准。它最主要的目的是为了在XML1.0或XML1.1文档节点树中定位节点所设计。目前有XPath1.0和XPath2.0两个版本。其中Xpath1.0是1999年成为W3C标准,而XPath2.0标准的确立是在2007年。W3C关于XPath的英文详细文档请见:http://www.w3.org/TR/xpath20/ 。

XPath是一种表达式语言,它的返回值可能是节点,节点集合,原子值,以及节点和原子值的混合等。XPath2.0是XPath1.0的超集。它是对XPath1.0的扩展,它可以支持更加丰富的数据类型,并且XPath2.0保持了对XPath1.0的相对很好的向后兼容性,几乎所有的XPath2.0的返回结果都可以和XPath1.0保持一样。另外XPath2.0也是XSLT2.0和XQuery1.0的用于查询定位节点的主表达式语言。XQuery1.0是对XPath2.0的扩展。关于在XSLT和XQuery中使用XPath表达式定位节点的知识在后面的实例中会有所介绍。

在学习XPath之前你应该对XML的节点,元素,属性,原子值(文本),处理指令,注释,根节点(文档节点),命名空间以及对节点间的关系如:父(Parent),子(Children),兄弟(Sibling),先辈(Ancestor),后代(Descendant)等概念有所了解。这里不在说明。

XPath路径表达式

在本小节下面的内容中你将可以学习到:

  • 路径表达式语法
  • 相对/绝对路径
  • 表达式上下文
  • 谓词(筛选表达式)及轴的概念
  • 运算符及特殊字符
  • 常用表达式实例
  • 函数及说明

这里给出一个实例Xml文件。下面的说明及实例都是基于该XML文件。

路径表达式语法:

  1. 路径 = 相对路径 | 绝对路径
  2. XPath路径表达式 = 步进表达式 | 相对路径 "/"步进表达式。
  3. 步进表达式=轴 节点测试 谓词

说明:

  1. 其中轴表示步进表达式选择的节点和当前上下文节点间的树状关系(层次关系),节点测试指定步进表达式选择的节点名称扩展名,谓词即相当于过滤表达式以进一步过滤细化节点集。
  2. 谓词可以是0个或多个。多个多个谓词用逻辑操作符and, or连接。取逻辑非用not()函数。
请看一个典型的XPath查询表达式:/messages/message//child::node()[@id=0],其中/messages/message是路径(绝对路径以"/"开始),child::是轴表示在子节点下选择,node()是节点测试表示选择所有的节点。[@id=0]是谓词,表示选择所有有属性id并且值为0的节点。
 
相对路径与绝对路径:
如果"/"处在XPath表达式开头则表示文档根元素,(表达式中间作为分隔符用以分割每一个步进表达式)如:/messages/message/subject是一种绝对路径表示法,它表明是从文档根开始查找节点。假设当前节点是在第一个message节点【/messages/message[1]】,则路径表达式subject(路径前没有"/")这种表示法称为相对路径,表明从当前节点开始查找。具体请见下面所述的"表达式上下文"。
表达式上下文(Context):
上下文其实表示一种环境。以明确当前XPath路径表达式处在什么样的环境下执行。例如同样一个路径表达式处在对根节点操作的环境和处在对某一个特定子节点操作的环境下执行所获得的结果可能是完全不一样的。也就是说XPath路径表达式计算结果取决于它所处的上下文。
XPath上下文基本有以下几种
  • 当前节点(./): 
    如./sender表示选择当前节点下的sender节点集合(等同于下面所讲的"特定元素",如:sender)
  • 父节点(../): 
    如../sender表示选择当前节点的父节点下的sender节点集合
  • 根元素(/): 
    如/messages表示选择从文档根节点下的messages节点集合.
  • 根节点(/*): 
    这里的*是代表所有节点,但是根元素只有一个,所以这里表示根节点。/*的返回结果和/messages返回的结果一样都是messages节点。
  • 递归下降(//): 
    如当前上下文是messages节点。则//sender将返回以下结果: 
    /messages//sender : 
    <sender>gkt1980@gmail.com</sender> 
    <sender>111@gmail.com</sender> 
    <sender>333@gmail.com</sender>

    /messages/message[1]//sender: 
    <sender>gkt1980@gmail.com</sender> 
    <sender>111@gmail.com</sender>

    我们可以看出XPath表达式返回的结果是:从当前节点开始递归步进搜索当前节点下的所有子节点找到满足条件的节点集。

  • 特定元素 
    如sender:表示选择当前节点下的sender节点集合,等同于(./sender)
注意:在执行XPath时一定要注意上下文。即当前是在哪个节点下执行XPath表达式。这在XMLDOM中很重要。如:在XMLDOM中的selectNodes,selectSingleNode方法的参数都是一个XPath表达式,此时这个XPath表达式的执行上下文就是调用这个方法的节点及它所在的环境。更多信息请参见:http://www.w3.org/TR/xpath20/
谓词(筛选表达式)及轴的概念
XPath的谓词即筛选表达式,类似于SQL的where子句.
轴名称
结果
ancestor
选取当前节点的所有先辈(父、祖父等)
ancestor-or-self
选取当前节点的所有先辈(父、祖父等)以及当前节点本身
attribute
选取当前节点的所有属性
child
选取当前节点的所有子元素。
descendant
选取当前节点的所有后代元素(子、孙等)。
descendant-or-self
选取当前节点的所有后代元素(子、孙等)以及当前节点本身。
following
选取文档中当前节点的结束标签之后的所有节点。
namespace
选取当前节点的所有命名空间节点
parent
选取当前节点的父节点。
preceding
直到所有这个节点的父辈节点,顺序选择每个父辈节点前的所有同级节点
preceding-sibling
选取当前节点之前的所有同级节点。
self
选取当前节点。
运算符及特殊字符:
运算符/特殊字符
说明
/
此路径运算符出现在模式开头时,表示应从根节点选择。
//
从当前节点开始递归下降,此路径运算符出现在模式开头时,表示应从根节点递归下降。
.
当前上下文。
..
当前上下文节点父级。
*
通配符;选择所有元素节点与元素名无关。(不包括文本,注释,指令等节点,如果也要包含这些节点请用node()函数)
@
属性名的前缀。
@*
选择所有属性,与名称无关。
:
命名空间分隔符;将命名空间前缀与元素名或属性名分隔。
( )
括号运算符(优先级最高),强制运算优先级。
[ ]
应用筛选模式(即谓词,包括"过滤表达式"和"轴(向前/向后)")。
[ ]
下标运算符;用于在集合中编制索引。
|
两个节点集合的联合,如://messages/message/to | //messages/message/cc
-
减法。
div,
浮点除法。
and, or
逻辑运算。
mod
求余。
not()
逻辑非
=
等于
!=
不等于
特殊比较运算符
< 或者 &lt;
<= 或者 &lt;=
> 或者 &gt;
>= 或者 &gt;=
需要转义的时候必须使用转义的形式,如在XSLT中,而在XMLDOM的scripting中不需要转义。
常用表达式实例:
/
Document Root文档根.
/*
选择文档根下面的所有元素节点,即根节点(XML文档只有一个根节点)
/node()
根元素下所有的节点(包括文本节点,注释节点等)
/text()
查找文档根节点下的所有文本节点
/messages/message
messages节点下的所有message节点
/messages/message[1]
messages节点下的第一个message节点
/messages/message[1]/self::node()
第一个message节点(self轴表示自身,node()表示选择所有节点)
/messages/message[1]/node()
第一个message节点下的所有子节点
/messages/message[1]/*[last()]
第一个message节点的最后一个子节点
/messages/message[1]/[last()]
Error,谓词前必须是节点或节点集
/messages/message[1]/node()[last()]
第一个message节点的最后一个子节点
/messages/message[1]/text()
第一个message节点的所有子节点
/messages/message[1]//text()
第一个message节点下递归下降查找所有的文本节点(无限深度)
/messages/message[1] /child::node()
/messages/message[1] /node()
/messages/message[position()=1]/node()
//message[@id=1] /node()
第一个message节点下的所有子节点
//message[@id=1] //child::node()
递归所有子节点(无限深度)
//message[position()=1]/node()
选择id=1的message节点以及id=0的message节点
/messages/message[1] /parent::*
Messages节点
/messages/message[1]/body/attachments/parent::node()
/messages/message[1]/body/attachments/parent::* /messages/message[1]/body/attachments/..
attachments节点的父节点。父节点只有一个,所以node()和* 返回结果一样。
(..也表示父节点. 表示自身节点)
//message[@id=0]/ancestor::*
Ancestor轴表示所有的祖辈,父,祖父等。
向上递归
//message[@id=0]/ancestor-or-self::*
向上递归,包含自身
//message[@id=0]/ancestor::node()
对比使用*,多一个文档根元素(Document root)
/messages/message[1]/descendant::node()
//messages/message[1]//node()
递归下降查找message节点的所有节点
/messages/message[1]/sender/following::*
查找第一个message节点的sender节点后的所有同级节点,并对每一个同级节点递归向下查找。
//message[@id=1]/sender/following-sibling::*
查找id=1的message节点的sender节点的所有后续的同级节点。
//message[@id=1]/datetime/@date
查找id=1的message节点的datetime节点的date属性
//message[@id=1]/datetime[@date]
//message/datetime[attribute::date]
查找id=1的message节点的所有含有date属性的datetime节点
//message[datetime]
查找所有含有datetime节点的message节点
//message/datetime/attribute::*
//message/datetime/attribute::node()
//message/datetime/@*
返回message节点下datetime节点的所有属性节点
//message/datetime[attribute::*]
//message/datetime[attribute::node()]
//message/datetime[@*]
//message/datetime[@node()]
选择所有含有属性的datetime节点
//attribute::*
选择根节点下的所有属性节点
//message[@id=0]/body/preceding::node()
顺序选择body节点所在节点前的所有同级节点。(查找顺序为:先找到body节点的顶级节点(根节点),得到根节点标签前的所有同级节点,执行完成后继续向下一级,顺序得到该节点标签前的所有同级节点,依次类推。)
注意:查找同级节点是顺序查找,而不是递归查找。
//message[@id=0]/body/preceding-sibling::node()
顺序查找body标签前的所有同级节点。(和上例一个最大的区别是:不从最顶层开始到body节点逐层查找。我们可以理解成少了一个循环,而只查找当前节点前的同级节点)
//message[@id=1]//*[namespace::amazon]
查找id=1的所有message节点下的所有命名空间为amazon的节点。
//namespace::*
文档中的所有的命名空间节点。(包括默认命名空间xmlns:xml)
//message[@id=0]//books/*[local-name()='book']
选择books下的所有的book节点,
注意:由于book节点定义了命名空间<amazone:book>.若写成//message[@id=0]//books/book则查找不出任何节点。
//message[@id=0]//books/*[local-name()='book' and namespace-uri()='http://www.amazon.com/books/schema']
选择books下的所有的book节点,(节点名和命名空间都匹配)
//message[@id=0]//books/*[local-name()='book'][year>2006]
选择year节点值>2006的book节点
//message[@id=0]//books/*[local-name()='book'][1]/year>2006
指示第一个book节点的year节点值是否大于2006.
返回xs:boolean: true
函数及说明: 
值得欣喜的是XPath函数和XSLT,XQuery等共享函数库,函数库为我们提供了功能丰富的各种函数的调用,我们也可以自定义自己的函数。这里不再对每个函数的用法逐一说明,英文好点的朋友直接去看看w3关于XPath函数的介绍吧:http://www.w3.org/TR/xquery-operators 。中文的可以参考这个网站, http://www.w3school.com.cn/xpath/xpath_functions.asp
 
XPath在DOM,XSLT及XQuery中的应用

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 
<html xmlns="http://www.w3.org/1999/xhtml"> 
<head> 
<title>XPath Test</title> 
</head> 
<body>

<script language="javascript" type="text/javascript"> 
var xmlDoc = new ActiveXObject("Microsoft.XMLDOM"); 
xmlDoc.async="false"; 
xmlDoc.load("messages.xml"); 
xmlDoc.setProperty("SelectionLanguage", "XPath"); 
    var sPath = "/messages/message[1]//books/*[local-name()='book']"; 
var bookNodes = xmlDoc.selectNodes(sPath);

document.write("<ul>"); 
for ( var i = 0; i < bookNodes.length; i++) { 
document.write("<li>" + bookNodes[i].childNodes[0].text + "</li>"); 

document.write("</ul>"); 
</script>

</body> 
</html>

注意
我们若使用new ActiveXObject("Microsoft.XMLDOM")则需要注意的是:因为早期的XMLDOM的SelectionLanguage属性默认是正则表达式,不是XPath语言。所以需要指定这样一条语句xmlDoc.setProperty("SelectionLanguage", "XPath"); 以支持XPath查询表达式。.
若没有指定SelectionLanguage属性值为XPath则要注意以下情况:
  1. 数组下标从0开始(我们知道在XPath查询表达式中数组下标是从1开始的)
  2. 不支持在XPath查询表达式中使用XPath函数。
XSLT: 
见:我的另外一篇关于如何使用XSLT的一个小示范http://www.cnblogs.com/ktgu/archive/2008/12/14/1354890.html
XQuery: 

xquery version "1.0";

<ul> 

let $i := 0 
for $x in doc("C:\Users\Administrator\Desktop\messages.xml")//message[@id=0]//books/*[local-name()='book'] 
where $x/year>2006 
order by $x/year descending 
return <li>{ data($x/name) } </li> 

</ul>

返回结果

<ul> 
    <li>Microsoft Visual C# 2008 Step by Step </li> 
    <li>Professional C# 2008 </li> 
</ul>

XPath总结(转)的更多相关文章

  1. xpath提取多个标签下的text

    title: xpath提取多个标签下的text author: 青南 date: 2015-01-17 16:01:07 categories: [Python] tags: [xpath,Pyth ...

  2. C#+HtmlAgilityPack+XPath带你采集数据(以采集天气数据为例子)

    第一次接触HtmlAgilityPack是在5年前,一些意外,让我从技术部门临时调到销售部门,负责建立一些流程和寻找潜在客户,最后在阿里巴巴找到了很多客户信息,非常全面,刚开始是手动复制到Excel, ...

  3. 在Java中使用xpath对xml解析

    xpath是一门在xml文档中查找信息的语言.xpath用于在XML文档中通过元素和属性进行导航.它的返回值可能是节点,节点集合,文本,以及节点和文本的混合等.在学习本文档之前应该对XML的节点,元素 ...

  4. XPath 学习二: 语法

    XPath 使用路径表达式来选取 XML 文档中的节点或节点集.节点是通过沿着路径 (path) 或者步 (steps) 来选取的. 下面列出了最有用的路径表达式: 表达式 描述 nodename 选 ...

  5. xpath 学习一: 节点

    xpath 中,有七种类型的节点: 元素.属性.文本.命名空间.处理指令.注释.以及根节点 树的根成为文档节点或者根节点. 节点关系: Parent, Children, sibling(同胞), A ...

  6. Python爬虫利器三之Xpath语法与lxml库的用法

    前面我们介绍了 BeautifulSoup 的用法,这个已经是非常强大的库了,不过还有一些比较流行的解析库,例如 lxml,使用的是 Xpath 语法,同样是效率比较高的解析方法.如果大家对 Beau ...

  7. 使用python+xpath 获取https://pypi.python.org/pypi/lxml/2.3/的下载链接

    使用python+xpath 获取https://pypi.python.org/pypi/lxml/2.3/的下载链接: 使用requests获取html后,分析html中的标签发现所需要的链接在& ...

  8. 关于robotframework,app,appium的xpath定位问题及常用方法

    关于类似的帖子好像很多,但是没有找到具体能帮我解决问题的办法.还是自己深究了好久才基本知道app上面的xpath定位和web上的不同点: 先放一个图: A,先说说不用xpath的场景,一般是用于存在i ...

  9. Selenium Xpath Tutorials - Identifying xpath for element with examples to use in selenium

    Xpath in selenium is close to must required. XPath is element locator and you need to provide xpath ...

  10. xpath定位中starts-with、contains和text()的用法

    starts-with 顾名思义,匹配一个属性开始位置的关键字 contains 匹配一个属性值中包含的字符串 text() 匹配的是显示文本信息,此处也可以用来做定位用 eg //input[sta ...

随机推荐

  1. Xcode4.4中,代码无法高亮、无法自动补全

    1.代码无法高亮显示:2.代码不能自动补全,或者给出提示建议:(当然这个补全的功能我在设置当中是打开的状态)3.新建一个项目,代码还是依然没有高亮显示,但是有补全功能:4.然后我就在网络上搜索了相关的 ...

  2. gulp安装

    1. npm install gulp -g    全局安装  npm install gulp --save-dev  安装文件内,纪录于package.json     接著安装插件,完成下列任务 ...

  3. elastic search 学习笔记

    Elastic search在数据分析的应用中相当于一个数据库的搜索引擎. 跟MySQL类似,它有自己的查询语言,只不过不是关系型数据库,属于NoSQL. 可以根据索引从分布式服务器文件系统中快速存取 ...

  4. 明解C语言,练习13-3,从文件中读入个人信息,按身高排序后显示

    #include <stdio.h> #define NUMBER 6 #define F_PATH "D:\\C_C++\\ec13-3\\hw.dat" typed ...

  5. Codeforces 193D Two Segments 解题报告

    先是在蓝桥杯的网站上看到一道题: 给出1~n的一个排列,求出区间内所有数是连续自然数的区间的个数.n<=50000. 由于数据较弱,即使用O(N^2)的算法也能拿到满分. 于是在CF上发现了这一 ...

  6. css3字阴影text-shadow

    看到text-shadow这句代码,眼尖的同学是不是觉得很熟悉?没错,前面我们已经学习过<css3基础教程五边框box-shadow>,而且这两者非常相近,只要以前的课程学好了,text- ...

  7. Linux下安装SVN服务(CentOS7下)

    1. 安装 centos(我这里使用的是CentOS7)下yum命令即可方便的完成安装 测试安装是否成功: 2. 建立版本库 创建svn数据目录(subversion默认是把/var/svn作为数据根 ...

  8. 子元素的margin-top影响父元素原因和解决办法

    这个问题会出现在所有浏览器当中,原因是css2.1盒子模型中规定, In this specification, the expression collapsing margins means tha ...

  9. ICE学习第二步-----从第一个程序了解ICE(HelloWorld)

    ICE(Internet Communications Engine)是一种面向对象的中间件平台,主要用于网络通讯.它为面向对象的“客户端-服务器”模型的应用提供了一组很好的工具和API接口.目前在全 ...

  10. linux安装时提示发生不正常错误问题

    跳过md5系统较检(每个系统版本都有一个md5编码唯一) 在安装CentOS时 提示 找不到磁盘,是否安装程序,选择安装程序进行"下一步" 提示: 发生不规则,不正常错误 原因:没 ...