常常在工做中会使用到XPath的相关知识,但每次总会在一些关键的地方不记得或不太清楚,因此免不了每次总要查一些零碎的知识,感受即很烦又浪费时间,因此对XPath概括及总结一下。node 在这篇文章中你将能学习到:函数
- XPath简介
- XPath 路径表达式详解
- XPath在DOM,XSLT及XQuery中的应用
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表达式定位节点的知识在后面的实例中会有所介绍。spa 在学习XPath以前你应该对XML的节点,元素,属性,原子值(文本),处理指令,注释,根节点(文档节点),命名空间以及对节点间的关系如:父(Parent),子(Children),兄弟(Sibling),先辈(Ancestor),后代(Descendant)等概念有所了解。这里不在说明。设计 XPath路径表达式递归 在本小节下面的内容中你将能够学习到:索引
- 路径表达式语法
- 相对/绝对路径
- 表达式上下文
- 谓词(筛选表达式)及轴的概念
- 运算符及特殊字符
- 经常使用表达式实例
- 函数及说明
这里给出一个实例Xml文件。下面的说明及实例都是基于该XML文件。ip
-
- 路径 = 相对路径 | 绝对路径
- XPath路径表达式 = 步进表达式 | 相对路径 "/"步进表达式。
- 步进表达式=轴 节点测试 谓词
说明:ci
- 其中轴表示步进表达式选择的节点和当前上下文节点间的树状关系(层次关系),节点测试指定步进表达式选择的节点名称扩展名,谓词即至关于过滤表达式以进一步过滤细化节点集。
- 谓词能够是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() |
逻辑非 |
= |
等于 |
!= |
不等于 |
特殊比较运算符 |
< 或者 < <= 或者 <= > 或者 > >= 或者 >= 须要转义的时候必须使用转义的形式,如在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节点 |
|