xml的xPath解析规则
一,为什么要用xpath技术
问题:当使用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
下面几个是常见的符号
/ 绝对路径 表示从xml的根位置开始或子元素(一个层次结构)
// 相对路径 表示不分任何层次结构的选择元素。
* 通配符 表示匹配所有元素
[] 条件 表示选择什么条件下的元素
@ 属性 表示选择属性节点
and 关系 表示条件的与关系(等价于&&)
text() 文本 表示选择文本内容
三,案例
3.1,删除id值为2的学生标签
/**
* 需求: 删除id值为2的学生标签
*/
Document doc = new SAXReader().read(new File("e:/student.xml"));
//1.查询id为2的学生标签
//使用xpath技术
Element stuElem = (Element)doc.selectSingleNode("//Student[@id='2']");
//2.删除标签
stuElem.detach();
//3.写出xml文件
FileOutputStream out = new FileOutputStream("e:/student.xml");
OutputFormat format = OutputFormat.createPrettyPrint();
format.setEncoding("utf-8");
XMLWriter writer = new XMLWriter(out,format);
writer.write(doc);
writer.close();
3.2,常用符号的应用
Document doc = new SAXReader().read(new File("./src/contact.xml"));
String xpath = "";
/**
* 1. / 绝对路径 表示从xml的根位置开始或子元素(一个层次结构)
*/
xpath = "/contactList";
xpath = "/contactList/contact";
/**
* 2. // 相对路径 表示不分任何层次结构的选择元素。
*/
xpath = "//contact/name";
xpath = "//name";
/**
* 3. * 通配符 表示匹配所有元素
*/
xpath = "/contactList/*"; //根标签contactList下的所有子标签
xpath = "/contactList//*";//根标签contactList下的所有标签(不分层次结构)
/**
* 4. [] 条件 表示选择什么条件下的元素
*/
//带有id属性的contact标签
xpath = "//contact[@id]";
//第二个的contact标签
xpath = "//contact[2]";
//选择最后一个contact标签
xpath = "//contact[last()]";
/**
* 5. @ 属性 表示选择属性节点
*/
xpath = "//@id"; //选择id属性节点对象,返回的是Attribute对象
xpath = "//contact[not(@id)]";//选择不包含id属性的contact标签节点
xpath = "//contact[@id='002']";//选择id属性值为002的contact标签
xpath = "//contact[@id='001' and @name='eric']";//选择id属性值为001,且name属性为eric的contact标签
/**
*6. text() 表示选择文本内容
*/
//选择name标签下的文本内容,返回Text对象
xpath = "//name/text()";
xpath = "//contact/name[text()='张三']";//选择姓名为张三的name标签
List<Node> list = doc.selectNodes(xpath);
for (Node node : list) {
System.out.println(node);
}
}
3.3,按照规定格式输出内容
<html>
<head>
<title>传智播客1月18号班通讯录</title>
<meta http-equiv="content-type" content="text/html; charset=UTF-8" />
</head>
<body>
<center><h1>12月16号就业班通讯录</h1></center>
<table border="1" align="center" id="contactForm">
<thead>
<tr><th>编号</th><th>姓名</th><th>性别</th><th>年龄</th><th>地址</th><th>电话</th></tr>
</thead>
<tbody>
<tr>
<td>001</td>
<td>张三</td>
<td>男</td>
<td>18</td>
<td>广州市天河区</td>
<td>134000000000</td>
</tr>
<tr>
<td>002</td>
<td>李四</td>
<td>女</td>
<td>20</td>
<td>广州市越秀区</td>
<td>13888888888</td>
</tr>
<tr>
<td>002</td>
<td>郭靖</td>
<td>男</td>
<td>30</td>
<td>广州市番禺区</td>
<td>1342214321</td>
</tr>
</tbody>
</table>
</body>
</html>
public static void main(String[] args) throws Exception{
Document doc = new SAXReader().read(new File("./src/personList.html"));
//System.out.println(doc);
//读取title标签
Element titleElem = (Element)doc.selectSingleNode("//title");
String title = titleElem.getText();
System.out.println(title);
/**
* 练习:读取联系人的所有信息
* 按照以下格式输出:
* 编号:001 姓名:张三 性别:男 年龄:18 地址:xxxx 电话: xxxx
* 编号:002 姓名:李四 性别:女 年龄:20 地址:xxxx 电话: xxxx
* ......
*/
//1.读取出所有tbody中的tr标签
List<Element> list = (List<Element>)doc.selectNodes("//tbody/tr");
//2.遍历
for (Element elem : list) {
//编号
//String id = ((Element)elem.elements().get(0)).getText();
String id = elem.selectSingleNode("td[1]").getText();
//姓名
String name = ((Element)elem.elements().get(1)).getText();
//性别
String gender = ((Element)elem.elements().get(2)).getText();
//年龄
String age = ((Element)elem.elements().get(3)).getText();
//地址
String address = ((Element)elem.elements().get(4)).getText();
//电话
String phone = ((Element)elem.elements().get(5)).getText();
System.out.println("编号:"+id+"\t姓名:"+name+"\t性别:"+
gender+"\t年龄:"+
age+"\t地址:"+address+
"\t电话:"+phone);
}
}
传智播客1月18号班通讯录 编号:001 姓名:张三 性别:男 年龄:18 地址:广州市天河区 电话:134000000000 编号:002 姓名:李四 性别:女 年龄:20 地址:广州市越秀区 电话:13888888888 编号:002 姓名:郭靖 性别:男 年龄:30 地址:广州市番禺区 电话:1342214321
补充
XPath 运算符
下面列出了可用在 XPath 表达式中的运算符:
| 运算符 | 描述 | 实例 | 返回值 |
|---|---|---|---|
| | | 计算两个节点集 | //book | //cd | 返回所有拥有 book 和 cd 元素的节点集 |
| + | 加法 | 6 + 4 | 10 |
| - | 减法 | 6 - 4 | 2 |
| * | 乘法 | 6 * 4 | 24 |
| div | 除法 | 8 div 4 | 2 |
| = | 等于 | 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。 |
| or | 或 | price=9.80 or price=9.70 |
如果 price 是 9.80,则返回 true。 如果 price 是 9.50,则返回 false。 |
| and | 与 | price>9.00 and price<9.90 |
如果 price 是 9.80,则返回 true。 如果 price 是 8.50,则返回 false。 |
| mod | 计算除法的余数 | 5 mod 2 | 1 |
xml的xPath解析规则的更多相关文章
- xml的SAX解析规则
一,为什么要用它 1.1,讲解 DOM解析原理:一次性把xml文档加载进内存,然后在内存中构建Document树. 对内存要求比较要. 缺点: 不适合读取大容量的xml文件,容易导致内存溢出. SAX ...
- xml的Dom4j解析规则
一,xml的样本 <?xml version="1.0" encoding="utf-8"?> <contactList> <co ...
- XML 树结构,语法规则,元素,属性,验证及其解析
XML 文档形成了一种树结构,它从"根部"开始,然后扩展到"枝叶". 一个 XML 文档实例 XML 文档使用简单的具有自我描述性的语法: <?xml v ...
- JAVA通过XPath解析XML性能比较(原创)
(转载请标明原文地址) 最近在做一个小项目,使用到XML文件解析技术,通过对该技术的了解和使用,总结了以下内容. 1 XML文件解析的4种方法 通常解析XML文件有四种经典的方法.基本的解析方式有两种 ...
- 利用XPath解析带有xmlns的XML文件
在.net中,编写读取xml 的程序中提示"未将对象引用设置到对象的实例",当时一看觉得有点奇怪.为什么在读取xml数据的时候也要实例化一个对象.google了才知道,xml文件中 ...
- java使用dom4j和XPath解析XML与.net 操作XML小结
最近研究java的dom4j包,使用 dom4j包来操作了xml 文件 包括三个文件:studentInfo.xml(待解析的xml文件), Dom4jReadExmple.java(解析的主要类), ...
- JAVA通过XPath解析XML性能比较
转自[http://www.cnblogs.com/mouse-coder/p/3451243.html] 最近在做一个小项目,使用到XML文件解析技术,通过对该技术的了解和使用,总结了以下内容. 1 ...
- Xpath解析xml
Xpath解析xml其实最主要的是查找xml文档中信息,而且不需要了解xml文档结构 package com.huawei.xml; import java.io.InputStream;import ...
- Xml二(解析思想)、
XML解析: * 解析xml可以做: * 如果xml作为配置文件:读取 * 如果xml作为传输文件:写,读 * xml解析思想: * DOM:将文档加载进内存,形成一颗dom树(document对象) ...
随机推荐
- JDK8的新特性——Lambda表达式
JDK8已经发布快4年的时间了,现在来谈它的新特性显得略微的有点“不合时宜”.尽管JDK8已不再“新”,但它的重要特性之一——Lambda表达式依然是不被大部分开发者所熟练运用,甚至不被开发者所熟知. ...
- nginx上支持.htaccess伪静态的配置实例
本文介绍下,在nginx上配置.htaccess伪静态的方法,有需要的朋友参考下吧. 在apache上.htaccess转向,只要apache编译的时候指明支持rewrite模块即可. 但是换到ngi ...
- Array 数组的排序 sort
JavaScript实现多维数组.对象数组排序,其实用的就是原生的sort()方法,用于对数组的元素进行排序.sort() 方法用于对数组的元素进行排序.语法如下:arrayObject.sort(s ...
- linux 中 svn 服务器搭建 重启
鉴于在搭建时,参考网上很多资料,网上资料在有用的同时,也坑了很多人 本文的目的,也就是想让后继之人在搭建svn服务器时不再犯错,不再被网上漫天的坑爹作品所坑害,故此总结 /******开始****** ...
- Oracle批量操作数据库
1:批量插入 <insert id="insertBatch" parameterType="Java.util.List" > insert in ...
- 终极解决方案:java.security.cert.CertificateException: Certificates does not conform to algorithm constraints
报错信息 javax.net.ssl.SSLHandshakeException: java.security.cert.CertificateException: Certificates does ...
- 一不小心把Mysql数据库的root的账号的权限给弄没啦,该怎么办
别急啊,现在只要你还能连接到Mysql,就问题不大! 首先,连接道Mysql,这里用Navicat进行讲解. 说明:root@localhost和root@127.0.0.1不是一个账号,也不是一回事 ...
- PHP文件头BOM头问题
前几天我们公司服务器出现了一个离奇的问题,服务器与本地文件代码完全一致,本地运行正常,到了测试环境服务器之后,各种问题一个又一个浮现,先是后台验证码不显示,以为是session写入失败,又是怀疑gd库 ...
- 买帽子 (hash)
思路:表示数字i出现的次数,在输入的同时记录每个数字出现的次数.最后从0枚举到1000判断第三个是否存在,存在则记录该数字. #include <stdio.h> #include < ...
- R实践 第二篇:创建数据集
准备数据是数据分析的第一步,由数据构成集合,我们称作数据集,数据集的结构是行列式的,行表示观测,列表示变量.把数据读入到R中,转换为合适的数据结构,能够提高数据分析的效率.在数据分析中,常用的存储数据 ...