使用Dom4j解析XML文档
1.Dom4j简介
- Dom4j是一个简单、灵活的开放源代码的库。Dom4j是由早期开发JDOM的人分离出来而后独立开发的。与JDOM不同的是,dom4j使用接口和抽象基类,虽然Dom4j的API相对要复杂一些,但它提供了比JDOM更好的灵活性。
- Dom4j是一个非常优秀的Java XML的API,具有性能优异、功能强大和极易使用的特点。现在很多软件采用的Dom4j,例如Hibernate,包括sun公司自的JAXM也用了Dom4j。
- 使用Dom4j开发,需下载dom4j相应的jar文件。可前往https://dom4j.github.io/进行相应版本的下载,在这里LZ选择了dom4j-2.1.0进行了下载。
在Dom4j中获取Document对象的方式有三种:
//1.读取XML文件,获得document对象
SAXReader reader = new SAXReader();
Document document = reader.read("src/book.xml");
//2.解析XML形式的文本,得到document对象.
String text = "<书名>书名>";
Document document = DocumentHelper.parseText(text);
//3.主动创建document对象.
Document document = DocumentHelper.createDocument();
//创建根节点
Element root = document.addElement("members");
3.使用Dom4j对xml文档进行基本操作
【使用Dom4j解析XML文档】xml代码示例:
<书架>
<书>
<书名 name="jxs">大话数据结构书名>
<作者>程杰作者>
<售价>38.00售价>
书>
<书>
<书名>MySQL必知必会书名>
<作者>Ben Forta作者>
<售价>23.00售价>
书>
书架>
基本操作代码示例:
package dom4j;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.SAXReader;
import org.dom4j.io.XMLWriter;
import org.junit.Test;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.List;
/**
* Created by jiangxs on 2017/10/11.
* 使用dom4j对xml文档进行解析
* CRUD
*/
public class Foo {/**
* 遍历xml文档中的所有标签
* */
@Test
public void listTag() throws DocumentException {
SAXReader reader = new SAXReader();
Document document = reader.read("src/book.xml");
Element element = document.getRootElement();
list(element);
}public void list(Element element){
System.out.println(element.getName());
List list = element.elements();
for (Element child : list){
list(child);
}
}/**
* 获取<书名 name="jxs">大话数据结构书名>节点内容
* */
@Test
public void test1() throws DocumentException {
SAXReader reader = new SAXReader();
Document document = reader.read("src/book.xml");
String text = document.getRootElement().element("书").element("书名").getText();
System.out.println(text);
}/**
* 获取<书名 name="jxs">大话数据结构书名>节点内容
* */
@Test
public void test2() throws DocumentException {
SAXReader reader = new SAXReader();
Document document = reader.read("src/book.xml");
Element bookName = document.getRootElement().element("书").element("书名");
System.out.println(bookName.attributeValue("name"));
}/**
* 向xml文档中添加一个售价节点
* */
@Test
public void test3() throws DocumentException, IOException {
SAXReader reader = new SAXReader();
Document document = reader.read("src/book.xml");
//创建需要添加的节点
Element element = DocumentHelper.createElement("售价");
element.setText("39.00");
//把节点挂到书下
document.getRootElement().element("书").add(element);
//使用pretty使生成的新节点按格式排列
OutputFormat format = OutputFormat.createPrettyPrint();
format.setEncoding("UTF-8");
//把更新内容写到xml下
//使用字节流不会由于两边格式不一致而出现乱码
XMLWriter writer = new XMLWriter(new FileOutputStream("src/book.xml"),format);
writer.write(document);
writer.close();
}/**
* 向xml文档中指定位置删除一个售价节点
* */
@Test
public void test5() throws DocumentException, IOException {
SAXReader reader = new SAXReader();
Document document = reader.read("src/book.xml");
//选择需要删除的节点
Element element = document.getRootElement().element("书").elements("售价").get(1);
element.getParent().remove(element);
//刷新
OutputFormat format = OutputFormat.createPrettyPrint();
format.setEncoding("UTF-8");
XMLWriter writer = new XMLWriter(new FileOutputStream("src/book.xml"),format);
writer.write(document);
writer.close();
}/**
* 向xml文档中指定位置修改一个售价节点
* */
@Test
public void test6() throws DocumentException, IOException {
SAXReader reader = new SAXReader();
Document document = reader.read("src/book.xml");
//选择需要修改的节点进行修改
Element element = document.getRootElement().element("书").elements("售价").get(1);
element.setText("55.00");
//刷新
OutputFormat format = OutputFormat.createPrettyPrint();
format.setEncoding("UTF-8");
XMLWriter writer = new XMLWriter(new FileOutputStream("src/book.xml"),format);
writer.write(document);
writer.close();
}
}
4.XPath的基本语法
下面的语法基于该xml文档
<书架>
<书>
<书名 name="jxs">大话数据结构书名>
<作者>程杰作者>
<售价>88.00售价>
<售价>55.00售价>
书>
<书>
<书名 name="sxj">MySQL必知必会书名>
<作者>Ben Forta作者>
<售价>23.00售价>
书>
书架>
选取节点
表达式 | 描述 |
---|---|
nodename | 选取此节点的所有子节点 |
/ | 从根节点选取 |
// | 从匹配选择的当前节点选择文档中的节点,而不考虑它们的位置 |
. | 选取当前节点 |
.. | 选取当前节点的父节点 |
@ | 选取属性 |
路径表达式 | 结果 |
---|---|
书架 | 选取”书架”元素的所有子节点 |
/书架 | 选取根元素”书架”(假如路径起始于正斜杠(/),则此路径始终代表到某元素的绝对路径) |
书架/书 | 选取书架的子元素所有书元素 |
//书 | 选取所有书子元素,而不管它们在文档中的位置 |
书架//书 | 选择属于书架元素的后代的所有书元素,而不管它们位于书架之下的什么位置 |
@name | 选取名为name的所有属性 |
谓语被嵌在方括号中。
在下面的表格中,我们列出了带有谓语的一些路径表达式,以及表达式的结果:
路径表达式 | 结果 |
---|---|
/书架/书[1] | 选取属于 书架 子元素的第一个 书 元素 |
/书架/书[last()] | 选取属于 书架 子元素的最后一个 书 元素 |
/书架/[last()-1] | 选取属于 书架 子元素的倒数第二个 书 元素 |
/书架/书[position()<3] | 选取最前面的两个属于 书架 元素的子元素的 书 元素。 |
//书名[@name] | 选取所有拥有名为 name 的属性的 书名 元素 |
//书名[@name=’jxs’] | 选取所有 书名 元素,且这些元素拥有值为 jxs 的 name 属性。 |
/书架/书[售价>30] | 选取 书架 元素的所有 书 元素,且其中的 售价 元素的值须大于 30.00。 |
/书架/书[售价>30.00]/书名 | 选取 书架 元素中的 书 元素的所有 书名 元素,且其中的 售价 元素的值须大于 30.00。 |
通配符 | 描述 |
---|---|
* | 匹配任何元素节点 |
@* | 匹配任何属性节点 |
node() | 匹配任何类型的节点 |
路径表达式 | 结果 |
---|---|
/书架/* | 选取 书 元素的所有子元素 |
//* | 获取文档中的所有元素 |
//title[@*] | 选取所有带属性的title元素 |
XPath小例子 示例程序1:
改代码的xml文件用的上述xml文件
package dom4j;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.Node;
import org.dom4j.io.SAXReader;
import org.junit.Test;
/**
* Created by jiangxs on 2017/10/16.
* 在dom4j中使用XPath
*/
public class XpathDemo {@Test
public void test1() throws DocumentException {
SAXReader reader = new SAXReader();
Document document = reader.read("src/book.xml");
//选择要查找的内容
Element element = (Element) document.selectNodes("//作者").get(0);
System.out.println(element.getText());
}
}
示例程序2:
package dom4j;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.Node;
import org.dom4j.io.SAXReader;
import org.junit.Test;
/**
* Created by jiangxs on 2017/10/16.
* 在dom4j中使用XPath
*/
public class XpathDemo {@Test
public void test2() throws DocumentException {
String name = "王五";
String password = "123";
SAXReader reader = new SAXReader();
Document document = reader.read("src/userlogging.xml");
Node node = document.selectSingleNode("//user[@username='"+name+"' and @password='"+password+"']");
if (node != null)
System.out.println("登录成功!欢迎您!");
else
System.out.println("登录名或密码错误,登录失败,请重试!");
}
}
示例程序2演示结果:
登录成功!欢迎您!Process finished with exit code 0
推荐阅读
- 由浅入深理解AOP
- 【译】20个更有效地使用谷歌搜索的技巧
- mybatisplus如何在xml的连表查询中使用queryWrapper
- MybatisPlus|MybatisPlus LambdaQueryWrapper使用int默认值的坑及解决
- MybatisPlus使用queryWrapper如何实现复杂查询
- iOS中的Block
- Linux下面如何查看tomcat已经使用多少线程
- 使用composer自动加载类文件
- android|android studio中ndk的使用
- 使用协程爬取网页,计算网页数据大小