XPath的概念:
XPath是一种定位XML文档的各个部分的语言,它还提供处理字符串,数字和布尔值的常用函数。XPath可以定位XML文档的元素和属性等部件。XPath提供的一星儿函数能够定位返回字符串或检测出字符串的长度,XPath还包括字符数据转换成数字类型和布尔类型的函数。
XPath从它的路径符号给出名称,它使用的语法铜URL类似,通常称XPath语句为XPath表达式。
XPath不是一种独立技术,它用于其它的技术如XSLT中,用XPath可以检索XML的元素和属性,可以XPath看做是XML的SQL。
XPath语法:
1.定位路径:他是一种选择节点集合的XPath表达式类型,通常使用“/”隔开的定位阶来构造定位路径。如/games/game,上述定位路径有两个定位阶。定位路径有两种类型:相对的和绝对的。相对的定位路径是由“/”分开的一个或多个定位阶的序列。绝对定位路径由“/”和后面的相对定位路径组成。
2.定位阶:他是定位路径的组成部分,由三部分组成:
1)一个轴:它规定了上下文节点和定位阶所选节点之间的关系。
2)一个节点测试:它规定了定位阶选择的阶段类型。
3)零或多个谓词,它们使用了表达式进一步改进节点的选择。
如XPath表达式"/games/game[@genre='rpg']",该表达式选择了所有genre属性值为rpg的位于games元素下的game元素。
3.节点测试:它通知XPath表达式运算的节点类型,节点测试通常都是源树种元素名称,如/games/game,该表达式有两个节点测试:games和game。
4.轴说明符:它用于明确指出要处理的节点测试的关系,如果要选games元素的所有子元素,则代码如下:child::games.
下面归纳了部分轴说明符
轴说明符 说明
child 节点的所有子节点
descendant 节点的所有后代节点
parent 节点的父节点
following-sibling 节点后面的兄弟节点
preceding-sibling 节点前面的兄弟节点
5.谓词:它是另一种进一步缩小节点选择范围的方法。XPath使用方括号[]来指定谓词,谓词使用XPath提供的函数提供测试,它可以访问属性(使用@符号)。
如前面出现过的XPath表达式"/games/game[@genre='rpg']",方括号[]中的“@genre='rpg'”就是谓词,该表达式用于测试位于games元素下的game元素的genre属性值是否为rpg。
XPath函数:
XPath函数使得用户能够处理字符串,数字和节点集合,下面列出了三个节点集合函数:
number last() 返回最后位置 如count(games/game)返回games元素下的game元素数目
number position() 返回当前位置 如games/game[last()]返回games元素下的最后一个game元素
number count(node-set) 返回结合参数中节点数目 如/games/game[position()=1]将返回games元素下的首个game元素。
下面使用开源包dom4j对XML文档进行XPath操作的例子:
将要处理的XML文档如下:
<?xml version="1.0" encoding="GBK"?>
<employees>
<employee lable="tech">
<id>0001</id>
<name>李白</name>
<title>程序员</title>
<skill>Java</skill>
<age>18</age>
</employee>
<employee lable="tech">
<id>0002</id>
<name>杜甫</name>
<title>高级程序员</title>
<skill>C#</skill>
<age>28</age>
</employee>
<employee lable="tech">
<id>0003</id>
<name>Andy</name>
<title>项目经理</title>
<skill>PPT</skill>
<age>38</age>
</employee>
<employee lable="admin">
<id>0004</id>
<name>Bill</name>
<title>部门经理</title>
<skill>Java</skill>
<age>48</age>
</employee>
<employee lable="admin">
<id>0005</id>
<name>Cindy</name>
<title>总经理</title>
<skill>C#</skill>
<age>58</age>
</employee>
</employees>
XPath示例程序:
package com.heyang;
import java.util.Iterator;
import java.util.List;
import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.XPath;
import org.dom4j.io.SAXReader;
/**
* dom4j的XPath解析示例
* @author: 何杨(heyang78@gmail.com)
* @date: 2009-9-27-上午09:59:52
*/
public class XPathSample{
public static void main(String[] args) throws Exception{
SAXReader reader = new SAXReader();
Document doc = reader.read(XPathSample.class.getResource("/Employee.xml").getPath());
// 1.XPath选择器,选择根节点employees下所有属性lable为tech的employee子节点
System.out.println("1.选择根节点employees下所有属性lable为tech的employee子节点");
XPath xpathSelector = DocumentHelper.createXPath("/employees/employee[@lable='tech']");
List results = xpathSelector.selectNodes(doc);
for ( Iterator iter = results.iterator(); iter.hasNext(); ) {
Element element = (Element) iter.next();
// 找到employee子节点的name子节点的文字打印
System.out.println(element.selectSingleNode("./name").getText());
}
// 2.打印名称为李白的employee节点的title
System.out.println("2.打印名称为李白的employee节点的title");
String title = doc.valueOf( "//employee[name='李白']/title" );
System.out.println(title);
// 3.XPath选择器,选择所有属性lable为admin的employee子节点的name子节点
System.out.println("3.选择所有属性lable为admin的employee子节点的name子节点");
XPath xpathSelector2 = DocumentHelper.createXPath("//employee[@lable='admin']/name");
List results2 = xpathSelector2.selectNodes(doc);
for ( Iterator iter = results2.iterator(); iter.hasNext(); ) {
Element element = (Element) iter.next();
System.out.println(element.getText());
}
// 4.XPath选择器,选择所有年龄节点大于20的employee子节点的name子节点
System.out.println("4.选择所有年龄节点大于20的employee子节点的name子节点");
XPath xpathSelector3 = DocumentHelper.createXPath("//employee[age>20]/name");
List results3 = xpathSelector3.selectNodes(doc);
for ( Iterator iter = results3.iterator(); iter.hasNext(); ) {
Element element = (Element) iter.next();
System.out.println(element.getText());
}
}
}
控制台输出:
1.选择根节点employees下所有属性lable为tech的employee子节点
李白
杜甫
Andy
2.打印名称为李白的employee节点的title
程序员
3.选择所有属性lable为admin的employee子节点的name子节点
Bill
Cindy
4.选择所有年龄节点大于20的employee子节点的name子节点
杜甫
Andy
Bill
Cindy
XPath相关参照文档(网络上搜索得到,不保证内容的完全正确性):
表达式 描述
节点名 选择所有该名称的节点集
/ 选择根节点
// 选择当前节点下的所有节点
. 选择当前节点
.. 选择父节点
@ 选择属性
示例
表达式 描述
bookstore 选择所有bookstore子节点
/bookstore 选择根节点bookstore
bookstore/book 在bookstore的子节点中选择所有名为book的节点
//book 选择xml文档中所有名为book的节点
bookstore//book 选择节点bookstore下的所有名为book为节点
//@lang 选择所有名为lang的属性
方括号[],用来更进一步定位选择的元素
表达式 描述
/bookstore/book[1] 选择根元素bookstore的book子元素中的第一个(注意: IE5以上浏览器中第一个元素是0)
/bookstore/book[last()] 选择根元素bookstore的book子元素中的最后一个
/bookstore/book[last()-1] 选择根元素bookstore的book子元素中的最后第二个
/bookstore/book[position()<3] 选择根元素bookstore的book子元素中的前两个
//title[@lang] 选择所有拥有属性lang的titile元素
//title[@lang='eng'] 选择所有属性值lang为eng的title元素
/bookstore/book[price>35.00] 选择根元素bookstore的book子元素中那些拥有price子元素且值大于35的
/bookstore/book[price>35.00]/title 选择根元素bookstore的book子元素中那些拥有price子元素且值大于35的title子元素
选择位置的节点
通配符 描述
* 匹配所有元素
@* 匹配所有属性节点
node() 匹配任何类型的节点
示例
表达式 描述
/bookstore/* 选择根元素bookstore的下的所有子元素
//* 选择文档中所有元素
//title[@*] 选择所有拥有属性的title元素
使用操作符“|”组合选择符合多个path的表达式