`
java-mans
  • 浏览: 11388888 次
文章分类
社区版块
存档分类
最新评论

xpath整理

 
阅读更多

Xpath文档

在这篇文章中你将能学习到:

◆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表达式定位节点的知识在后面的实例中会有所介绍。在学习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 :

gkt1980@gmail.com

111@gmail.com

333@gmail.com

/messages/message[1]//sender:

gkt1980@gmail.com

111@gmail.com

我们可以看出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节点

/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节点定义了命名空间.若写成//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中的应用

DOM:

注意:

我们若使用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查询表达式:

xquery version "1.0"; 

{

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

{ data($x/name) }

}

返回结果:

Microsoft Visual C# 2008 Step by Step 

Professional C# 2008

这里只是非常简单的介绍一下应用,XPath的其他应用场合和应用技巧大家自己总结吧。



XPath由W3C的 XPath 1.0 标准 描述.本教程通过实例来展示XPath的一些特性.

你可以从以下内容开始:

1。基本的XPath语法类似于在一个文件系统中定位文件,如果路径以斜线 / 开始, 那么该路径就表示到一个元素的绝对路径

/AAA
选择根元素AAA

<AAA>
<BBB/>
<CCC/>
<BBB/>
<BBB/>
<DDD>
<BBB/>
</DDD>
<CCC/>
</AAA>

/AAA/CCC
选择AAA的所有CCC子元素

<AAA>
<BBB/>
<CCC/>
<BBB/>
<BBB/>
<DDD>
<BBB/>
</DDD>
<CCC/>
</AAA>

/AAA/DDD/BBB
选择AAA的子元素DDD的所有子元素

<AAA>
<BBB/>
<CCC/>
<BBB/>
<BBB/>
<DDD>
<BBB/>
</DDD>
<CCC/>
</AAA>

2。如果路径以双斜线 // 开头, 则表示选择文档中所有满足双斜线//之后规则的元素(无论层级关系)
//BBB
选择所有BBB元素

<AAA>
<BBB/>
<CCC/>
<BBB/>
<DDD>
<BBB/>
</DDD>
<CCC>
<DDD>
<BBB/>
<BBB/>
</DDD>
</CCC>
</AAA>

//DDD/BBB
选择所有父元素是DDD的BBB元素

<AAA>
<BBB/>
<CCC/>
<BBB/>
<DDD>
<BBB/>
</DDD>
<CCC>
<DDD>
<BBB/>
<BBB/>
</DDD>
</CCC>
</AAA>

3。星号 * 表示选择所有由星号之前的路径所定位的元素
/AAA/CCC/DDD/*
选择所有路径依附于/AAA/CCC/DDD的元素

<AAA>
<XXX>
<DDD>
<BBB/>
<BBB/>
<EEE/>
<FFF/>
</DDD>
</XXX>
<CCC>
<DDD>
<BBB/>
<BBB/>
<EEE/>
<FFF/>
</DDD>
</CCC>
<CCC>
<BBB>
<BBB>
<BBB/>
</BBB>
</BBB>
</CCC>
</AAA>

/*/*/*/BBB
选择所有的有3个祖先元素的BBB元素

<AAA>
<XXX>
<DDD>
<BBB/>
<BBB/>
<EEE/>
<FFF/>
</DDD>
</XXX>
<CCC>
<DDD>
<BBB/>
<BBB/>
<EEE/>
<FFF/>
</DDD>
</CCC>
<CCC>
<BBB>
<BBB>
<BBB/>
</BBB>
</BBB>
</CCC>
</AAA>

//*
选择所有元素

<AAA>
<XXX>
<DDD>
<BBB/>
<BBB/>
<EEE/>
<FFF/>
</DDD>
</XXX>
<CCC>
<DDD>
<BBB/>
<BBB/>
<EEE/>
<FFF/>
</DDD>
</CCC>
<CCC>
<BBB>
<BBB>
<BBB/>
</BBB>
</BBB>
</CCC>
</AAA>

4。方块号里的表达式可以进一步的指定元素, 其中数字表示元素在选择集里的位置, 而last()函数则表示选择集中的最后一个元素.
/AAA/BBB[1]
选择AAA的第一个BBB子元素

<AAA>
<BBB/>
<BBB/>
<BBB/>
<BBB/>
</AAA>

/AAA/BBB[last()]
选择AAA的最后一个BBB子元素

<AAA>
<BBB/>
<BBB/>
<BBB/>
<BBB/>
</AAA>

5。
//@id
选择所有的id属性

<AAA>
<BBB id = "b1"/>
<BBB id = "b2"/>
<BBB name = "bbb"/>
<BBB/>
</AAA>

//BBB[@id]
选择有id属性的BBB元素

<AAA>
<BBB id = "b1"/>
<BBB id = "b2"/>
<BBB name = "bbb"/>
<BBB/>
</AAA>

//BBB[@name]
选择有name属性的BBB元素

<AAA>
<BBB id = "b1"/>
<BBB id = "b2"/>
<BBB name = "bbb"/>
<BBB/>
</AAA>

//BBB[@*]
选择有任意属性的BBB元素

<AAA>
<BBB id = "b1"/>
<BBB id = "b2"/>
<BBB name = "bbb"/>
<BBB/>
</AAA>

//BBB[not(@*)]
选择没有属性的BBB元素

<AAA>
<BBB id = "b1"/>
<BBB id = "b2"/>
<BBB name = "bbb"/>
<BBB/>
</AAA>

6。属性的值可以被用来作为选择的准则, normalize-space函数删除了前部和尾部的空格, 并且把连续的空格串替换为一个单一的空格
//BBB[@id='b1']
选择含有属性id且其值为'b1'的BBB元素

<AAA>
<BBB id = "b1"/>
<BBB name = " bbb "/>
<BBB name = "bbb"/>
</AAA>

//BBB[@name='bbb']
选择含有属性name且其值为'bbb'的BBB元素

<AAA>
<BBB id = "b1"/>
<BBB name = " bbb "/>
<BBB name = "bbb"/>
</AAA>

//BBB[normalize-space(@name)='bbb']
选择含有属性name且其值(在用normalize-space函数去掉前后空格后)为'bbb'的BBB元素

<AAA>
<BBB id = "b1"/>
<BBB name = " bbb "/>
<BBB name = "bbb"/>
</AAA>

7。count()函数可以计数所选元素的个数
//*[count(BBB)=2]
选择含有2个BBB子元素的元素

<AAA>
<CCC>
<BBB/>
<BBB/>
<BBB/>
</CCC>
<DDD>
<BBB/>
<BBB/>
</DDD>
<EEE>
<CCC/>
<DDD/>
</EEE>
</AAA>

//*[count(*)=2]
选择含有2个子元素的元素

<AAA>
<CCC>
<BBB/>
<BBB/>
<BBB/>
</CCC>
<DDD>
<BBB/>
<BBB/>
</DDD>
<EEE>
<CCC/>
<DDD/>
</EEE>
</AAA>

//*[count(*)=3]
选择含有3个子元素的元素

<AAA>
<CCC>
<BBB/>
<BBB/>
<BBB/>
</CCC>
<DDD>
<BBB/>
<BBB/>
</DDD>
<EEE>
<CCC/>
<DDD/>
</EEE>
</AAA>

8。name()函数返回元素的名称, start-with()函数在该函数的第一个参数字符串是以第二个参数字符开始的情况返回true, contains()函数当其第一个字符串参数包含有第二个字符串参数时返回true.
//*[name()='BBB']
选择所有名称为BBB的元素(这里等价于//BBB)

<AAA>
<BCC>
<BBB/>
<BBB/>
<BBB/>
</BCC>
<DDB>
<BBB/>
<BBB/>
</DDB>
<BEC>
<CCC/>
<DBD/>
</BEC>
</AAA>

//*[starts-with(name(),'B')]
选择所有名称以"B"起始的元素

<AAA>
<BCC>
<BBB/>
<BBB/>
<BBB/>
</BCC>
<DDB>
<BBB/>
<BBB/>
</DDB>
<BEC>
<CCC/>
<DBD/>
</BEC>
</AAA>

//*[contains(name(),'C')]
选择所有名称包含"C"的元素

<AAA>
<BCC>
<BBB/>
<BBB/>
<BBB/>
</BCC>
<DDB>
<BBB/>
<BBB/>
</DDB>
<BEC>
<CCC/>
<DBD/>
</BEC>
</AAA>

9。string-length函数返回字符串的字符数,你应该用&lt;替代<, 用&gt;代替>
//*[string-length(name()) = 3]
选择名字长度为3的元素

<AAA>
<Q/>
<SSSS/>
<BB/>
<CCC/>
<DDDDDDDD/>
<EEEE/>
</AAA>

//*[string-length(name()) < 3]
选择名字长度小于3的元素

<AAA>
<Q/>
<SSSS/>
<BB/>
<CCC/>
<DDDDDDDD/>
<EEEE/>
</AAA>

//*[string-length(name()) > 3]
选择名字长度大于3的元素

<AAA>
<Q/>
<SSSS/>
<BB/>
<CCC/>
<DDDDDDDD/>
<EEEE/>
</AAA>

10。多个路径可以用分隔符 | 合并在一起
//CCC | //BBB
选择所有的CCC和BBB元素

<AAA>
<BBB/>
<CCC/>
<DDD>
<CCC/>
</DDD>
<EEE/>
</AAA>

/AAA/EEE | //BBB
选择所有的BBB元素和所有是AAA的子元素的EEE元素

<AAA>
<BBB/>
<CCC/>
<DDD>
<CCC/>
</DDD>
<EEE/>
</AAA>

/AAA/EEE | //DDD/CCC | /AAA | //BBB
可以合并的路径数目没有限制

<AAA>
<BBB/>
<CCC/>
<DDD>
<CCC/>
</DDD>
<EEE/>
</AAA>

11。child轴(axis)包含上下文节点的子元素, 作为默认的轴,可以忽略不写.
/AAA
等价于 /child::AAA

<AAA>
<BBB/>
<CCC/>
</AAA>

/child::AAA
等价于/AAA

<AAA>
<BBB/>
<CCC/>
</AAA>

/AAA/BBB
等价于/child::AAA/child::BBB

<AAA>
<BBB/>
<CCC/>
</AAA>

/child::AAA/child::BBB
等价于/AAA/BBB

<AAA>
<BBB/>
<CCC/>
</AAA>

/child::AAA/BBB
二者都可以被合并

<AAA>
<BBB/>
<CCC/>
</AAA>

12。descendant (后代)轴包含上下文节点的后代,一个后代是指子节点或者子节点的子节点等等, 因此descendant轴不会包含属性和命名空间节点.
/descendant::*
选择文档根元素的所有后代.即所有的元素被选择

<AAA>
<BBB>
<DDD>
<CCC>
<DDD/>
<EEE/>
</CCC>
</DDD>
</BBB>
<CCC>
<DDD>
<EEE>
<DDD>
<FFF/>
</DDD>
</EEE>
</DDD>
</CCC>
</AAA>

/AAA/BBB/descendant::*
选择/AAA/BBB的所有后代元素

<AAA>
<BBB>
<DDD>
<CCC>
<DDD/>
<EEE/>
</CCC>
</DDD>
</BBB>
<CCC>
<DDD>
<EEE>
<DDD>
<FFF/>
</DDD>
</EEE>
</DDD>
</CCC>
</AAA>

//CCC/descendant::*
选择在祖先元素中有CCC的所有元素

<AAA>
<BBB>
<DDD>
<CCC>
<DDD/>
<EEE/>
</CCC>
</DDD>
</BBB>
<CCC>
<DDD>
<EEE>
<DDD>
<FFF/>
</DDD>
</EEE>
</DDD>
</CCC>
</AAA>

//CCC/descendant::DDD
选择所有以CCC为祖先元素的DDD元素

<AAA>
<BBB>
<DDD>
<CCC>
<DDD/>
<EEE/>
</CCC>
</DDD>
</BBB>
<CCC>
<DDD>
<EEE>
<DDD>
<FFF/>
</DDD>
</EEE>
</DDD>
</CCC>
</AAA>

13。parent轴(axis)包含上下文节点的父节点, 如果有父节点的话
//DDD/parent::*
选择DDD元素的所有父节点

<AAA>
<BBB>
<DDD>
<CCC>
<DDD/>
<EEE/>
</CCC>
</DDD>
</BBB>
<CCC>
<DDD>
<EEE>
<DDD>
<FFF/>
</DDD>
</EEE>
</DDD>
</CCC>
</AAA>

14。ancestor轴(axis)包含上下节点的祖先节点, 该祖先节点由其上下文节点的父节点以及父节点的父节点等等诸如此类的节点构成,所以ancestor轴总是包含有根节点,除非上下文节点就是根节点本身.
/AAA/BBB/DDD/CCC/EEE/ancestor::*
选择一个绝对路径上的所有节点

<AAA>
<BBB>
<DDD>
<CCC>
<DDD/>
<EEE/>
</CCC>
</DDD>
</BBB>
<CCC>
<DDD>
<EEE>
<DDD>
<FFF/>
</DDD>
</EEE>
</DDD>
</CCC>
</AAA>

//FFF/ancestor::*
选择FFF元素的祖先节点

<AAA>
<BBB>
<DDD>
<CCC>
<DDD/>
<EEE/>
</CCC>
</DDD>
</BBB>
<CCC>
<DDD>
<EEE>
<DDD>
<FFF/>
</DDD>
</EEE>
</DDD>
</CCC>
</AAA>

15。following-sibling轴(axis)包含上下文节点之后的所有兄弟节点
/AAA/BBB/following-sibling::*

<AAA>
<BBB>
<CCC/>
<DDD/>
</BBB>
<XXX>
<DDD>
<EEE/>
<DDD/>
<CCC/>
<FFF/>
<FFF>
<GGG/>
</FFF>
</DDD>
</XXX>
<CCC>
<DDD/>
</CCC>
</AAA>

//CCC/following-sibling::*

<AAA>
<BBB>
<CCC/>
<DDD/>
</BBB>
<XXX>
<DDD>
<EEE/>
<DDD/>
<CCC/>
<FFF/>
<FFF>
<GGG/>
</FFF>
</DDD>
</XXX>
<CCC>
<DDD/>
</CCC>
</AAA>

16。preceding-sibling 轴(axis)包含上下文节点之前的所有兄弟节点
/AAA/XXX/preceding-sibling::*

<AAA>
<BBB>
<CCC/>
<DDD/>
</BBB>
<XXX>
<DDD>
<EEE/>
<DDD/>
<CCC/>
<FFF/>
<FFF>
<GGG/>
</FFF>
</DDD>
</XXX>
<CCC>
<DDD/>
</CCC>
</AAA>

//CCC/preceding-sibling::*

<AAA>
<BBB>
<CCC/>
<DDD/>
</BBB>
<XXX>
<DDD>
<EEE/>
<DDD/>
<CCC/>
<FFF/>
<FFF>
<GGG/>
</FFF>
</DDD>
</XXX>
<CCC>
<DDD/>
</CCC>
</AAA>

17。following轴(axis)包含同一文档中按文档顺序位于上下文节点之后的所有节点, 除了祖先节点,属性节点和命名空间节点
/AAA/XXX/following::*

<AAA>
<BBB>
<CCC/>
<ZZZ>
<DDD/>
<DDD>
<EEE/>
</DDD>
</ZZZ>
<FFF>
<GGG/>
</FFF>
</BBB>
<XXX>
<DDD>
<EEE/>
<DDD/>
<CCC/>
<FFF/>
<FFF>
<GGG/>
</FFF>
</DDD>
</XXX>
<CCC>
<DDD/>
</CCC>
</AAA>

//ZZZ/following::*

<AAA>
<BBB>
<CCC/>
<ZZZ>
<DDD/>
<DDD>
<EEE/>
</DDD>
</ZZZ>
<FFF>
<GGG/>
</FFF>
</BBB>
<XXX>
<DDD>
<EEE/>
<DDD/>
<CCC/>
<FFF/>
<FFF>
<GGG/>
</FFF>
</DDD>
</XXX>
<CCC>
<DDD/>
</CCC>
</AAA>

18。following轴(axis)包含同一文档中按文档顺序位于上下文节点之前的所有节点, 除了祖先节点,属性节点和命名空间节点
/AAA/XXX/preceding::*

<AAA>
<BBB>
<CCC/>
<ZZZ>
<DDD/>
</ZZZ>
</BBB>
<XXX>
<DDD>
<EEE/>
<DDD/>
<CCC/>
<FFF/>
<FFF>
<GGG/>
</FFF>
</DDD>
</XXX>
<CCC>
<DDD/>
</CCC>
</AAA>

//GGG/preceding::*

<AAA>
<BBB>
<CCC/>
<ZZZ>
<DDD/>
</ZZZ>
</BBB>
<XXX>
<DDD>
<EEE/>
<DDD/>
<CCC/>
<FFF/>
<FFF>
<GGG/>
</FFF>
</DDD>
</XXX>
<CCC>
<DDD/>
</CCC>
</AAA>

19。descendant-or-self 轴(axis)包含上下文节点本身和该节点的后代节点
/AAA/XXX/descendant-or-self::*

<AAA>
<BBB>
<CCC/>
<ZZZ>
<DDD/>
</ZZZ>
</BBB>
<XXX>
<DDD>
<EEE/>
<DDD/>
<CCC/>
<FFF/>
<FFF>
<GGG/>
</FFF>
</DDD>
</XXX>
<CCC>
<DDD/>
</CCC>
</AAA>

//CCC/descendant-or-self::*

<AAA>
<BBB>
<CCC/>
<ZZZ>
<DDD/>
</ZZZ>
</BBB>
<XXX>
<DDD>
<EEE/>
<DDD/>
<CCC/>
<FFF/>
<FFF>
<GGG/>
</FFF>
</DDD>
</XXX>
<CCC>
<DDD/>
</CCC>
</AAA>

20。ancestor-or-self 轴(axis)包含上下文节点本身和该节点的祖先节点
/AAA/XXX/DDD/EEE/ancestor-or-self::*

<AAA>
<BBB>
<CCC/>
<ZZZ>
<DDD/>
</ZZZ>
</BBB>
<XXX>
<DDD>
<EEE/>
<DDD/>
<CCC/>
<FFF/>
<FFF>
<GGG/>
</FFF>
</DDD>
</XXX>
<CCC>
<DDD/>
</CCC>
</AAA>

//GGG/ancestor-or-self::*

<AAA>
<BBB>
<CCC/>
<ZZZ>
<DDD/>
</ZZZ>
</BBB>
<XXX>
<DDD>
<EEE/>
<DDD/>
<CCC/>
<FFF/>
<FFF>
<GGG/>
</FFF>
</DDD>
</XXX>
<CCC>
<DDD/>
</CCC>
</AAA>

21。ancestor, descendant, following, preceding 和self轴(axis)分割了XML文档(忽略属性节点和命名空间节点), 不能交迭, 而一起使用则包含所有节点
//GGG/ancestor::*

<AAA>
<BBB>
<CCC/>
<ZZZ/>
</BBB>
<XXX>
<DDD>
<EEE/>
<FFF>
<HHH/>
<GGG>
<JJJ>
<QQQ/>
</JJJ>
<JJJ/>
</GGG>
<HHH/>
</FFF>
</DDD>
</XXX>
<CCC>
<DDD/>
</CCC>
</AAA>

//GGG/descendant::*

<AAA>
<BBB>
<CCC/>
<ZZZ/>
</BBB>
<XXX>
<DDD>
<EEE/>
<FFF>
<HHH/>
<GGG>
<JJJ>
<QQQ/>
</JJJ>
<JJJ/>
</GGG>
<HHH/>
</FFF>
</DDD>
</XXX>
<CCC>
<DDD/>
</CCC>
</AAA>

//GGG/following::*

<AAA>
<BBB>
<CCC/>
<ZZZ/>
</BBB>
<XXX>
<DDD>
<EEE/>
<FFF>
<HHH/>
<GGG>
<JJJ>
<QQQ/>
</JJJ>
<JJJ/>
</GGG>
<HHH/>
</FFF>
</DDD>
</XXX>
<CCC>
<DDD/>
</CCC>
</AAA>

//GGG/preceding::*

<AAA>
<BBB>
<CCC/>
<ZZZ/>
</BBB>
<XXX>
<DDD>
<EEE/>
<FFF>
<HHH/>
<GGG>
<JJJ>
<QQQ/>
</JJJ>
<JJJ/>
</GGG>
<HHH/>
</FFF>
</DDD>
</XXX>
<CCC>
<DDD/>
</CCC>
</AAA>

//GGG/self::*

<AAA>
<BBB>
<CCC/>
<ZZZ/>
</BBB>
<XXX>
<DDD>
<EEE/>
<FFF>
<HHH/>
<GGG>
<JJJ>
<QQQ/>
</JJJ>
<JJJ/>
</GGG>
<HHH/>
</FFF>
</DDD>
</XXX>
<CCC>
<DDD/>
</CCC>
</AAA>

//GGG/ancestor::* | //GGG/descendant::* | //GGG/following::* | //GGG/preceding::* | //GGG/self::*

<AAA>
<BBB>
<CCC/>
<ZZZ/>
</BBB>
<XXX>
<DDD>
<EEE/>
<FFF>
<HHH/>
<GGG>
<JJJ>
<QQQ/>
</JJJ>
<JJJ/>
</GGG>
<HHH/>
</FFF>
</DDD>
</XXX>
<CCC>
<DDD/>
</CCC>
</AAA>

22。div运算符做浮点除法运算, mod运算符做求余运算, floor函数返回不大于参数的最大整数(趋近于正无穷), ceiling返回不小于参数的最小整数(趋近于负无穷)
//BBB[position() mod 2 = 0 ]
选择偶数位置的BBB元素

<AAA>
<BBB/>
<BBB/>
<BBB/>
<BBB/>
<BBB/>
<BBB/>
<BBB/>
<BBB/>
<CCC/>
<CCC/>
<CCC/>
</AAA>

//BBB[ position() = floor(last() div 2 + 0.5) or position() = ceiling(last() div 2 + 0.5) ]
选择中间的BBB元素

<AAA>
<BBB/>
<BBB/>
<BBB/>
<BBB/>
<BBB/>
<BBB/>
<BBB/>
<BBB/>
<CCC/>
<CCC/>
<CCC/>
</AAA>

//CCC[ position() = floor(last() div 2 + 0.5) or position() = ceiling(last() div 2 + 0.5) ]
选择中间的CCC元素

<AAA>
<BBB/>
<BBB/>
<BBB/>
<BBB/>
<BBB/>
<BBB/>
<BBB/>
<BBB/>
<CCC/>
<CCC/>
<CCC/>
</AAA>

分享到:
评论

相关推荐

    xpath入门教程整理

    xpath入门教程整理、值得下载、不差这一分、xpath解析xml结构非常牛。

    JsoupXpath

    整理JsoupXpath( https://github.com/zhegexiaohuozi/JsoupXpath)是一款纯Java开发的使用xpath解析提取html内容的解析器,xpath语法分析与执行完全独立,html的DOM树生成借助Jsoup,故命名为JsoupXpath. 为了在java...

    XpathDemo.zip

    HtmlCleaner能够重新整理HTML文档的每个元素并生成结构良好(Well-Formed)的 HTML 文档。默认它遵循的规则是类似于大部份web浏览器为创文档对象模型所使用的规则。然而,用户可以提供自定义tag和规则组来进行过滤和...

    xPath学习教程(全)

    XPath 是一门在 XML 文档中查找信息的语言。XPath 可用来在 XML 文档中对元素和属性进行遍历。...资料整理来源:http://www.cnblogs.com/zhaozhan/archive/2009/09/09/1563617.html 内附:dom4j教程(全)一份

    xpath使用手册

    归纳整理的xpath使用手册,在自动化工作中,xpath使用很频繁。

    XPath介绍-图文版(XML简介,含实例)

    XPath介绍-图文版;自己整理的,原文在这里:http://www.w3pop.com/learn/view/p/1/o/0/doc/xpath_intro/

    XPath 工具手册(语法、轴、函数等)

    XPath的工具性手册,非教程,适合对于XPath有初步了解,但对其中的全部功能不是很清楚的人。本人从网上搜集资料,整理而成,以分享。

    无涯教程(LearnFk)-Xpath教程完整离线版.pdf

    无涯教程网(learnfk)整理提供:XPath即为XML路径语言,它是一种用来确定XML文档中某部分位置的语言。

    Python使用xpath读取xml文件的最简单方法

    xml文件目前获取数据最简单的方法还是使用xpath,通过网上的多次查询与整理,我认为目前我使用的方法比较容易理解和使用。 共享给朋友们试试看。

    正则表达式和XPATH

    大数据采集,爬取数据必用表达式,精华整理版,你值得拥有

    XSL、XPATH技术文档

    本人学习xsl、xpath是在网上收集的资料,按照一定的思路整理,对初学xsl、xpath有一定的帮助

    Python Xpath 的使用

    正则表达式 笔记整理 Python requests 模块 在用 Python 实现爬虫时,可以使用 requests 库访问资源,然后用正则表达式提取信息。 但是,这里会有一些繁琐,因为正则表达式的书写是比较严格的,万一有一个地方写错了...

    xpath css cheat sheet by灰蓝.pdf

    由灰蓝整理,selenium webdriver自动化测试人员常用xpath与css定位速查表,web自动化测试人员必备手边资料

    java selenium XPath 定位实现方法

    本文主要介绍java selenium XPath,这里整理了XPath的资料,并附实现方法,有需要的小伙伴可以参考下

    xpath css cheat sheet by 灰蓝.pdf

    灰蓝整理总结,selenium webdriver自动化测试定位xpath与css速查表,包括父子、兄弟关系的定位,网页自动化测试人员手边必备文档。

    XPATH 通俗教程

    个人学习之余整理的一些XPATH教程,虽然不是非常全面,但个人觉得都是重点

    xpath简介_动力节点Java学院整理

    xpath就是选择XML文件中节点的方法。下面通过本文给大家分享xpath的相关知识,感兴趣的朋友一起学习吧

    htmltidy:整理和测试R中HTML和XML内容的XPath查询

    整理和测试有关HTML和XML内容的XPath查询 描述 HTML文档可以是美丽而原始的。 它们也可能是可悲的,邪恶的,畸形的恶魔生成物。 现在,您可以整理HTML和XHTML,然后再使用您喜欢的尖括号处理工具进行处理,而不仅仅...

    酒店商城源码Java-fengchao:蜂巢爬虫系统是一套只需要定义XPath,就可实现爬取网站,APP的系统,支持多种解析方式(XPath,

    (部分代码整理中,开源plan) 下载方式: 支持java标准库, HttpClient库, PhantomJs, JBrowser , Selenium-Firefox,Chrome, MockDownload, FileDownload, ShellDownload; 解析方式: 支持HTML XPath, J

    个人整理的python爬虫:个人代码和笔记合集

    个人整理的python爬虫基础学习代码和笔记: 包括: 00:Python基础 01.Urllib 02.Xpath解析 03.selenium 04.requests 05.scrapy

Global site tag (gtag.js) - Google Analytics