XML学习总结(四)——Dom4j使用Xpath语法读取xml文件

    xpath是一门在xml文档中查找信息的语言。xpath用于在XML文档中通过元素和属性进行导航。它的返回值可能是节点,节点集合,文本,以及节点和文本的混合等。

    在学习本文档之前应该对XML的节点,元素,属性,文本,处理指令,注释,根节点,命名空间以及节点关系有一定的了解以及对xpath也有了解。

本文主要介绍:Java中使用xpath操作对xml操作。

一、导入jar包

1.导入xPath支持的jar包。

jaxen-1.1-beta-6.jar(首先要先导入dom4j包,dom4j下载地址:http://www.dom4j.org/dom4j-1.6.1/)。

2、在Java中使用xpath方法,主要有两点:

List<Node> selectNodes("xpath表达式"); 查询多个节点对象

Node selectSingleNode("xpath表达式"); 查询一个节点对象

二、案例

案例一:下面就用实例说明使用方法。

一、selectNodes使用方法:

复制代码
 1 package com.vastsum.demo;
 2 
 3 import java.io.File;
 4 import java.io.FileOutputStream;
 5 import java.util.List;
 6 
 7 import org.dom4j.Document;
 8 import org.dom4j.Element;
 9 import org.dom4j.Node;
10 import org.dom4j.io.OutputFormat;
11 import org.dom4j.io.SAXReader;
12 import org.dom4j.io.XMLWriter;
13 
14 /**
15  * 
16  * @author shutu008
17  *selectNode的使用方法
18  */
19 public class xpathDemo {
20 
21     public static void main(String[] args) throws Exception {
22 
23     Document doc = new SAXReader().read(new File("./src/contact.xml"));
24         
25         /**
26          * @param xpath 表示xpath语法变量
27          */
28     String xpath="";
29         
30         /**
31          * 1.      /      绝对路径      表示从xml的根位置开始或子元素(一个层次结构)
32          */
33         xpath = "/contactList";
34         xpath = "/contactList/contact";
35         
36         /**
37          * 2. //     相对路径       表示不分任何层次结构的选择元素。
38          */
39         xpath = "//contact/name";
40         xpath = "//name";
41         
42         /**
43          * 3. *      通配符         表示匹配所有元素
44          */
45         xpath = "/contactList/*"; //根标签contactList下的所有子标签
46         xpath = "/contactList//*";//根标签contactList下的所有标签(不分层次结构)
47         
48         /**
49          * 4. []      条件           表示选择什么条件下的元素
50          */
51         //带有id属性的contact标签
52         xpath = "//contact[@id]";
53         //第二个的contact标签
54         xpath = "//contact[2]";
55         //选择最后一个contact标签
56         xpath = "//contact[last()]";
57         
58         /**
59          * 5. @     属性            表示选择属性节点
60          */
61         xpath = "//@id"; //选择id属性节点对象,返回的是Attribute对象
62         xpath = "//contact[not(@id)]";//选择不包含id属性的contact标签节点
63         xpath = "//contact[@id='002']";//选择id属性值为002的contact标签
64         xpath = "//contact[@id='001' and @name='eric']";//选择id属性值为001,且name属性为eric的contact标签
65         
66         /**
67          *6.  text()   表示选择文本内容
68          */
69         //选择name标签下的文本内容,返回Text对象
70         xpath = "//name/text()";
71         xpath = "//contact/name[text()='张三']";//选择姓名为张三的name标签
72         
73         
74         List<Node> list = doc.selectNodes(xpath);
75         for (Node node : list) {
76             System.out.println(node);
77         }
78     
79         //写出xml文件
80         //输出位置
81         FileOutputStream out = new FileOutputStream("d:/contact.xml");
82         
83         //指定格式
84         OutputFormat format = OutputFormat.createPrettyPrint();
85         format.setEncoding("utf-8");
86         XMLWriter writer = new XMLWriter(out,format);
87         
88         //写出内容
89         writer.write(doc);
90         
91         //关闭资源
92         writer.close();
93         
94     }
95     
96 
97 }
复制代码

二、selectSingleNode的使用方法

复制代码
 1 package com.vastsum.demo;
 2 
 3 import java.io.File;
 4 import java.util.Iterator;
 5 
 6 import org.dom4j.Attribute;
 7 import org.dom4j.Document;
 8 import org.dom4j.Element;
 9 import org.dom4j.io.SAXReader;
10 
11 /**
12  * 
13  * @author shutu008
14  *selectSingleNode的使用
15  */
16  public class xpathDemo1{
17      public static void main(String[] args) throws Exception{
18          //读取XML文件,获得document对象
19         SAXReader saxReader = new SAXReader();    
20         Document doc = saxReader.read(new File("./src/contact.xml"));
21         
22         //使用xpath获取某个节点
23         String xpath = "";
24         
25         //对contact元素 id="001"的节点,操作
26         xpath = "//contact[@id = '001']";
27         Element contactElem =    (Element)doc.selectSingleNode(xpath);
28         
29         //设置这个节点的属性值
30         contactElem.addAttribute("name", "001");
31         
32         //输出这个节点的所有属性值
33         for(Iterator it = contactElem.attributeIterator();it.hasNext();){
34         Attribute conAttr = (Attribute)it.next();
35         String conTxt = conAttr.getValue();
36         String conAttrName = conAttr.getName();
37         System.out.println(conAttrName+" = "+conTxt);
38         }
39         
40      }
41  }
复制代码

 备注:以下是操作的xml文件

复制代码
 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <contactList id="0">
 3     <contact id="001" class="style" name="lisi">
 4         <name>张三</name>
 5         <age>20</age>
 6         <phone>134222223333</phone>
 7         <email>[email protected]</email>
 8         <qq>432221111</qq>
 9     </contact>
10     <contact id="002">
11         <name>李四</name>
12         <age>20</age>
13         <phone>134222225555</phone>
14         <email>[email protected]</email>
15         <qq>432222222</qq>
16     </contact>
17     <contactTwo>
18         <name>王五</name>
19         <age>32</age>
20         <phone>465431341</phone>
21         <emali>[email protected]</emali>
22         <qq>46164694</qq>
23     </contactTwo>
24     <test>测试</test>
25     <test>其他用途</test>
26 </contactList>

二、案例2

Demo:

src目录下 employee.xml文件

[xhtml]  view plain  copy
  1. <span style="font-size: small;" mce_style="font-size: small;"><?xml version="1.0" encoding="utf-8"?>  
  2. <root>  
  3.     <employee id="1">  
  4.         <name>wTang</name>  
  5.         <age>19</age>  
  6.         <high>173</high>          
  7.     </employee>  
  8.     <employee id="2">  
  9.         <name>wTang2</name>  
  10.         <age>20</age>  
  11.         <high>180</high>          
  12.     </employee>  
  13. </root></span>  

例如要获得id为1或者2的employee节点:

[java]  view plain  copy
  1. <span style="font-size: small;" mce_style="font-size: small;">package com.wt.dom4j;  
  2. import java.util.List;  
  3. import org.dom4j.Document;  
  4. import org.dom4j.Element;  
  5. import org.dom4j.io.SAXReader;  
  6. /** 
  7.  * Dom4j基础操作 
  8.  *  
  9.  * @author wTang 
  10.  * @editTime 2011年3月16日0:38:10 
  11.  *  
  12.  */  
  13. public class Dom4jParser {  
  14.     public static void main(String[] args) {  
  15.         try {  
  16.             SAXReader sax = new SAXReader();  
  17.             // 获得dom4j的文档对象  
  18.             Document root = sax.read(Dom4jParser.class.getClassLoader()  
  19.                     .getResourceAsStream("employee.xml"));  
  20.             // 得到database节点  
  21.             Element database = (Element) root  
  22.                     .selectSingleNode("//employee[@id='2']");  
  23.             List list = database.elements(); // 得到database元素下的子元素集合  
  24.             /* 
  25.              * 循环遍历集合中的每一个元素 将每一个元素的元素名和值在控制台中打印出来 
  26.              */  
  27.             for (Object obj : list) {  
  28.                 Element element = (Element) obj;  
  29.                 // getName()是元素名,getText()是元素值  
  30.                 System.out  
  31.                         .println(element.getName() + ": " + element.getText());  
  32.             }  
  33.         } catch (Exception e) {  
  34.             e.printStackTrace();  
  35.         }  
  36.     }  
  37. }</span>  

表达式:Element database = (Element) root.selectSingleNode("//employee[@id='2']");

输出为:

name: wTang2

age: 20

high: 180

表达式:  Element database = (Element) root.selectSingleNode("/root/employee[1]");

输出为:

name: wTang

age: 19

high: 173

我们可以给id里面的值做个参数, 封装为方法即可给外界调用. 

//     表示      从匹配选择的当前节点选择文档中的节点,而不考虑它们的位置。

/      表示      从根节点选取。 

@和jq的属性选择器类似  选择id=2为2的节点

[1] 表示获取employee的第一个元素,[2]就表示第二个了.

Xpath的语法灵活多变,只写这么点了.读取单个节点可以选择Xpath.

疑问:

xPath好像不能一次读取整个xml文件  

比如:  /root//employee   

返回的是一个封装的List  长度为3

如果是List做嵌套那么List的长度应该是2,再嵌套2个List.

结果只读取到了1个employee(3个节点).Xpath应该是不支持批量读取的吧. 

如果可以的话还请你告诉我下.

三、文档说明

Xpath语法官方文档:

<?xml version="1.0" encoding="ISO-8859-1"?>

<bookstore>

<book>

  <title lang="eng">Harry Potter</title>

  <price>29.99</price>

</book>

<book>

  <title lang="eng">Learning XML</title>

  <price>39.95</price>

</book>

</bookstore>

选取节点

XPath 使用路径表达式在 XML 文档中选取节点。节点是通过沿着路径或者 step 来选取的。

下面列出了最有用的路径表达式:

表达式

描述

nodename

选取此节点的所有子节点。

/

从根节点选取。

//

从匹配选择的当前节点选择文档中的节点,而不考虑它们的位置。

.

选取当前节点。

..

选取当前节点的父节点。

@

选取属性。

实例

在下面的表格中,我们已列出了一些路径表达式以及表达式的结果:

路径表达式

结果

bookstore

选取 bookstore 元素的所有子节点。

/bookstore

选取根元素 bookstore。

注释:假如路径起始于正斜杠( / ),则此路径始终代表到某元素的绝对路径!

bookstore/book

选取属于 bookstore 的子元素的所有 book 元素。

//book

选取所有 book 子元素,而不管它们在文档中的位置。

bookstore//book

选择属于 bookstore 元素的后代的所有 book 元素,而不管它们位于 bookstore 之下的什么位置。

//@lang

选取名为 lang 的所有属性。

谓语(Predicates)

谓语用来查找某个特定的节点或者包含某个指定的值的节点。

谓语被嵌在方括号中。

实例

在下面的表格中,我们列出了带有谓语的一些路径表达式,以及表达式的结果:

路径表达式

结果

/bookstore/book[1]

选取属于 bookstore 子元素的第一个 book 元素。

/bookstore/book[last()]

选取属于 bookstore 子元素的最后一个 book 元素。

/bookstore/book[last()-1]

选取属于 bookstore 子元素的倒数第二个 book 元素。

/bookstore/book[position()<3]

选取最前面的两个属于 bookstore 元素的子元素的 book 元素。

//title[@lang]

选取所有拥有名为 lang 的属性的 title 元素。

//title[@lang='eng']

选取所有 title 元素,且这些元素拥有值为 eng 的 lang 属性。

/bookstore/book[price>35.00]

选取 bookstore 元素的所有 book 元素,且其中的 price 元素的值须大于 35.00。

/bookstore/book[price>35.00]/title

选取 bookstore 元素中的 book 元素的所有 title 元素,且其中的 price 元素的值须大于 35.00。

选取未知节点

XPath 通配符可用来选取未知的 XML 元素。

通配符

描述

*

匹配任何元素节点。

@*

匹配任何属性节点。

node()

匹配任何类型的节点。

实例

在下面的表格中,我们列出了一些路径表达式,以及这些表达式的结果:

路径表达式

结果

/bookstore/*

选取 bookstore 元素的所有子元素。

//*

选取文档中的所有元素。

//title[@*]

选取所有带有属性的 title 元素。

选取若干路径
通过在路径表达式中使用“|”运算符,您可以选取若干个路径。
实例

在下面的表格中,我们列出了一些路径表达式,以及这些表达式的结果:

路径表达式

结果

//book/title | //book/price

选取 book 元素的所有 title 和 price 元素。

//title | //price

选取文档中的所有 title 和 price 元素。

/bookstore/book/title | //price

选取属于 bookstore 元素的 book 元素的所有 title 元素,以及文档中所有的 price 元素。

参考:https://blog.csdn.net/chenweitang123/article/details/6252263

猜你喜欢

转载自blog.csdn.net/qq_36501591/article/details/80536219