当柳上原的风吹向天际的时候...

真正的快乐来源于创造

  BlogJava :: 首页 :: 联系 :: 聚合  :: 管理
  368 Posts :: 1 Stories :: 201 Comments :: 0 Trackbacks
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的表达式

posted on 2009-09-27 10:56 何杨 阅读(450) 评论(0)  编辑  收藏