Xpath语法格式总结

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

Xpath语法格式总结
经常在⼯作中会使⽤到XPath的相关知识,但每次总会在⼀些关键的地⽅不记得或不太清楚,所以免不了每次总要查⼀些零碎的知识,感觉即很烦⼜浪费时间,所以对XPath归纳及总结⼀下。

在这篇⽂章中你将能学习到:
XPath简介
XPath 路径表达式详解
XPath在DOM,XSLT及XQuery中的应⽤
XPath简介
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⽂件。

<?xml version="1.0" encoding="UTF-8"?>
<!-- edited with XMLSpy v2008 rel. 2 sp2 () by Administrator -->
<?xml-stylesheet type="text/xsl" href="messages.xsl" rel="external nofollow" ?>
<messages>
<message id="1">
<sender>gukaitong@</sender>
<to>anonymous@
<group name="IT">
<address>111@</address>
<address>222@</address>
<address>aaa@</address>
<address>bbb@</address>
<address>ccc@</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@</sender>
<to>gukaitong@</to>
<body>
We strongly recommend the following books
<books xmlns:amazon="/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@</sender>
<to>444@</to>
<subject>No title</subject>
<body/>
</message>
</messages>
路径表达式语法:
路径 = 相对路径 | 绝对路径
XPath路径表达式 = 步进表达式 | 相对路径 "/"步进表达式。

步进表达式=轴节点测试谓词
说明:
其中轴表⽰步进表达式选择的节点和当前上下⽂节点间的树状关系(层次关系),节点测试指定步进表达式选择的节点名称扩展名,谓词即相当于过滤表达式以进⼀步过滤细化节点集。

谓词可以是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@</sender>
<sender>111@</sender>
<sender>333@</sender>
/messages/message[1]//sender:
<sender>gkt1980@</sender>
<sender>111@</sender>
我们可以看出XPath表达式返回的结果是:从当前节点开始递归步进搜索当前节点下的所有⼦节点找到满⾜条件的节点集。

特定元素
如sender:表⽰选择当前节点下的sender节点集合,等同于(./sender)
谓词(筛选表达式)及轴的概念:
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::*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()='/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在DOM,XSLT及XQuery中的应⽤
DOM:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="/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则要注意以下情况:
数组下标从0开始(我们知道在XPath查询表达式中数组下标是从1开始的)不⽀持在XPath查询表达式中使⽤XPath函数。

总结
以上就是本⽂关于Xpath语法格式总结的全部内容,希望对⼤家有所帮助。

感兴趣的朋友可以参阅:、、等,有什么问题可以随时留⾔,欢迎⼤家讨论交流。

相关文档
最新文档