xml的xPath解析规则

一,为什么要用xpath技术

假如你现在还在为自己的技术担忧,假如你现在想提升自己的工资,假如你想在职场上获得更多的话语权,假如你想顺利的度过35岁这个魔咒,假如你想体验BAT的工作环境,那么现在请我们一起开启提升技术之旅吧,详情请点击http://106.12.206.16:8080/qingruihappy/index.html

问题:当使用dom4j查询比较深的层次结构的节点(标签,属性,文本),比较麻烦!!!

二,xpath的规则

2.1,/根元素的案例

 

 

/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.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>                              

 

 2.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>                              

 

 2.4,方块号里的表达式可以进一步的指定元素, 其中数字表示元素在选择集里的位置, 而last()函数则表示选择集中的最后一个元素.

 

/AAA/BBB[1]
选择AAA的第一个BBB子元素

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

 

 

 

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

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

 

 2.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>                              

 2.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>                              

 

 2.7,总结

还有其它的很多的语法,请详见XPathTutorial这个api

下面几个是常见的符号

1 /      绝对路径      表示从xml的根位置开始或子元素(一个层次结构)
2                 //     相对路径       表示不分任何层次结构的选择元素。
3                 *      通配符         表示匹配所有元素
4                 []      条件           表示选择什么条件下的元素
5                 @     属性            表示选择属性节点
6                 and     关系          表示条件的与关系(等价于&&7                 text()    文本           表示选择文本内容

 

 三,案例

3.1,删除id值为2的学生标签

 1     /**
 2          * 需求: 删除id值为2的学生标签
 3          */
 4         Document doc = new SAXReader().read(new File("e:/student.xml"));
 5         
 6         //1.查询id为2的学生标签
 7         //使用xpath技术
 8         Element stuElem = (Element)doc.selectSingleNode("//Student[@id='2']");
 9 
10         //2.删除标签
11         stuElem.detach();
12         
13         //3.写出xml文件
14         FileOutputStream out = new FileOutputStream("e:/student.xml");
15         OutputFormat format = OutputFormat.createPrettyPrint();
16         format.setEncoding("utf-8");
17         XMLWriter writer = new XMLWriter(out,format);
18         writer.write(doc);
19         writer.close();

 

3.2,常用符号的应用 

 1         Document doc = new SAXReader().read(new File("./src/contact.xml"));
 2         
 3         String xpath = "";
 4         
 5         /**
 6          * 1.      /      绝对路径      表示从xml的根位置开始或子元素(一个层次结构)
 7          */
 8         xpath = "/contactList";
 9         xpath = "/contactList/contact";
10         
11         /**
12          * 2. //     相对路径       表示不分任何层次结构的选择元素。
13          */
14         xpath = "//contact/name";
15         xpath = "//name";
16         
17         /**
18          * 3. *      通配符         表示匹配所有元素
19          */
20         xpath = "/contactList/*"; //根标签contactList下的所有子标签
21         xpath = "/contactList//*";//根标签contactList下的所有标签(不分层次结构)
22         
23         /**
24          * 4. []      条件           表示选择什么条件下的元素
25          */
26         //带有id属性的contact标签
27         xpath = "//contact[@id]";
28         //第二个的contact标签
29         xpath = "//contact[2]";
30         //选择最后一个contact标签
31         xpath = "//contact[last()]";
32         
33         /**
34          * 5. @     属性            表示选择属性节点
35          */
36         xpath = "//@id"; //选择id属性节点对象,返回的是Attribute对象
37         xpath = "//contact[not(@id)]";//选择不包含id属性的contact标签节点
38         xpath = "//contact[@id='002']";//选择id属性值为002的contact标签
39         xpath = "//contact[@id='001' and @name='eric']";//选择id属性值为001,且name属性为eric的contact标签
40         
41         /**
42          *6.  text()   表示选择文本内容
43          */
44         //选择name标签下的文本内容,返回Text对象
45         xpath = "//name/text()";
46         xpath = "//contact/name[text()='张三']";//选择姓名为张三的name标签
47         
48         
49         List<Node> list = doc.selectNodes(xpath);
50         for (Node node : list) {
51             System.out.println(node);
52         }
53     }

 

3.3,按照规定格式输出内容 

 1 <html>
 2     <head>
 3         <title>传智播客1月18号班通讯录</title>
 4         <meta http-equiv="content-type" content="text/html; charset=UTF-8" />
 5     </head>
 6     <body>
 7         <center><h1>12月16号就业班通讯录</h1></center>
 8         <table border="1" align="center" id="contactForm">
 9             <thead>    
10                 <tr><th>编号</th><th>姓名</th><th>性别</th><th>年龄</th><th>地址</th><th>电话</th></tr>
11             </thead>
12             <tbody>
13                 <tr>
14                 <td>001</td>
15                 <td>张三</td>
16                 <td>男</td>
17                 <td>18</td>
18                 <td>广州市天河区</td>
19                 <td>134000000000</td>
20                 </tr>
21                 <tr>
22                 <td>002</td>
23                 <td>李四</td>
24                 <td>女</td>
25                 <td>20</td>
26                 <td>广州市越秀区</td>
27                 <td>13888888888</td>
28                 </tr>
29                 <tr>
30                 <td>002</td>
31                 <td>郭靖</td>
32                 <td>男</td>
33                 <td>30</td>
34                 <td>广州市番禺区</td>
35                 <td>1342214321</td>
36                 </tr>
37             </tbody>
38         </table>
39     </body>
40 </html>
 1 public static void main(String[] args) throws Exception{
 2         Document doc = new SAXReader().read(new File("./src/personList.html"));
 3         //System.out.println(doc);
 4         
 5         //读取title标签
 6         Element titleElem = (Element)doc.selectSingleNode("//title");
 7         String title = titleElem.getText();
 8         System.out.println(title);
 9         
10         /**
11          * 练习:读取联系人的所有信息
12          * 按照以下格式输出:
13          *          编号:001 姓名:张三 性别:男 年龄:18 地址:xxxx 电话: xxxx
14          *       编号:002 姓名:李四 性别:女 年龄:20 地址:xxxx 电话: xxxx
15          *       ......
16          */
17         //1.读取出所有tbody中的tr标签
18         List<Element> list = (List<Element>)doc.selectNodes("//tbody/tr");
19         //2.遍历
20         for (Element elem : list) {
21             //编号
22             //String id = ((Element)elem.elements().get(0)).getText();
23             String id = elem.selectSingleNode("td[1]").getText();
24             //姓名
25             String name = ((Element)elem.elements().get(1)).getText();
26             //性别
27             String gender = ((Element)elem.elements().get(2)).getText();
28             //年龄
29             String age = ((Element)elem.elements().get(3)).getText();
30             //地址
31             String address = ((Element)elem.elements().get(4)).getText();
32             //电话
33             String phone = ((Element)elem.elements().get(5)).getText();
34             
35             System.out.println("编号:"+id+"\t姓名:"+name+"\t性别:"+
36                                 gender+"\t年龄:"+
37                                 age+"\t地址:"+address+
38                                 "\t电话:"+phone);
39         }
40     }
1 传智播客1月18号班通讯录
2 编号:001    姓名:张三    性别:男    年龄:18    地址:广州市天河区    电话:134000000000
3 编号:002    姓名:李四    性别:女    年龄:20    地址:广州市越秀区    电话:13888888888
4 编号:002    姓名:郭靖    性别:男    年龄:30    地址:广州市番禺区    电话:1342214321

 补充

 

 

XPath 运算符

下面列出了可用在 XPath 表达式中的运算符:

运算符描述实例返回值
|计算两个节点集//book | //cd返回所有拥有 book 和 cd 元素的节点集
+加法6 + 410
-减法6 - 42
*乘法6 * 424
div除法8 div 42
=等于price=9.80

如果 price 是 9.80,则返回 true。

如果 price 是 9.90,则返回 false。

!=不等于price!=9.80

如果 price 是 9.90,则返回 true。

如果 price 是 9.80,则返回 false。

<小于price<9.80

如果 price 是 9.00,则返回 true。

如果 price 是 9.90,则返回 false。

<=小于或等于price<=9.80

如果 price 是 9.00,则返回 true。

如果 price 是 9.90,则返回 false。

>大于price>9.80

如果 price 是 9.90,则返回 true。

如果 price 是 9.80,则返回 false。

>=大于或等于price>=9.80

如果 price 是 9.90,则返回 true。

如果 price 是 9.70,则返回 false。

orprice=9.80 or price=9.70

如果 price 是 9.80,则返回 true。

如果 price 是 9.50,则返回 false。

andprice>9.00 and price<9.90

如果 price 是 9.80,则返回 true。

如果 price 是 8.50,则返回 false。

mod计算除法的余数5 mod 21

假如你现在还在为自己的技术担忧,假如你现在想提升自己的工资,假如你想在职场上获得更多的话语权,假如你想顺利的度过35岁这个魔咒,假如你想体验BAT的工作环境,那么现在请我们一起开启提升技术之旅吧,详情请点击http://106.12.206.16:8080/qingruihappy/index.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值