一、Dom4j 技术概述
先是 Jdom 在 dom 基础上进行了封装,而 dom4j 又对 jdom 进行了封装。
DOM4J 是一个开源的,基于 Java 的库来解析 XML 文档,它具有高度的灵活性,高性能和内存效率的 API。这是 java 的优化,使用 Java 集合像列表和数组。它可以使用 DOM,SAX,XPath 和 XSLT。它解析大型 XML 文档时具有极低的内存占用。
二、DOM4j 类库
1、类库
官网下载需要的 jar 包:
2、使用
dom4j 的 jar 包:
docs 是文档目录:
在 docs 里面找到 index.html ,快速入门
三、DOM4j 解析步骤
步骤:
- 先加载 xml 文件创建 Document 对象
- 通过 Document 对象拿到根元素对象
- 通过根元素.elelemts(标签名); 可以返回一个集合, 这个集合里放着。 所有你指定的标签名的元素对象
- 获取需要操作的元素,进行相应的操作
XML 文件:
<?xml version="1.0" encoding="UTF-8"?>
<books>
<book sn="123">
<name>Java</name>
<price>9.9</price>
<author>老张</author>
</book>
<book sn="456">
<name>Python</name>
<price>99.99</price>
<author>老李</author>
</book>
</books>
测试解析文件:
/*
* dom4j 获取 Documet 对象
*/
@Test
public void getDocument() throws DocumentException {
// 要创建一个 Document 对象, 需要我们先创建一个 SAXReader 对象
SAXReader reader = new SAXReader();
// 这个对象用于读取 xml 文件, 然后返回一个 Document。
Document document = reader.read("src/books.xml");
// 打印到控制台, 看看是否创建成功
System.out.println(document);
}
解析 XML 文件:
/*
* 读取 xml 文件中的内容
*/
@Test
public void readXML() throws DocumentException {
// 需要分四步操作:
// 第一步, 通过创建 SAXReader 对象。 来读取 xml 文件, 获取 Document 对象
// 第二步, 通过 Document 对象。 拿到 XML 的根元素对象
// 第三步, 通过根元素对象。 获取所有的 book 标签对象
// 第四步, 遍历每个 book 标签对象。 然后获取到 book 标签对象内的每一个元素, 再通过 getText() 方法拿到起始标签和结束标签之间的文本内容
// 第一步, 通过创建 SAXReader 对象。 来读取 xml 文件, 获取 Document 对象
SAXReader reader = new SAXReader();
Document document = reader.read("src/books.xml");
// 第二步, 通过 Document 对象。 拿到 XML 的根元素对象
Element root = document.getRootElement();
// 打印测试
// Element.asXML() 它将当前元素转换成为 String 对象
// System.out.println( root.asXML() );
// 第三步, 通过根元素对象。 获取所有的 book 标签对象
// Element.elements(标签名)它可以拿到当前元素下的指定的子元素的集合
List<Element> books = root.elements("book");
// 第四步, 遍历每个 book 标签对象。 然后获取到 book 标签对象内的每一个元素,
for (Element book : books) {
// 测试
// System.out.println(book.asXML());
// 拿到 book 下面的 name 元素对象
Element nameElement = book.element("name");
// 拿到 book 下面的 price 元素对象
Element priceElement = book.element("price");
// 拿到 book 下面的 author 元素对象
Element authorElement = book.element("author");
// 再通过 getText() 方法拿到起始标签和结束标签之间的文本内容
System.out.println("书名" + nameElement.getText() + " , 价格:"
+ priceElement.getText() + ", 作者: " + authorElement.getText());
}
}
四、Dom4j 解析器使用 XPath 语言操作 xml 文档
1、导入支持 xpath 的 jar 包:jaxen-1.1-beta-6.jar
2、dom4j 里面提供了两个方法,用来支持 XPath
selectNodes("XPath 表达式"); 表示获取多个节点
selectSingleNode("XPath 表达式"); 表示获取单个节点
Demo:
@Test
public void test() throws Exception {
//创建核心解析器对象
SAXReader saxReader = new SAXReader();
//加载配置文件,获取文档对象document
InputStream is = Dom4jDemo.class.getClassLoader().getResourceAsStream("student.xml");
//获取 document 对象
Document document = saxReader.read(is);
//使用xpath语法快速查找元素,返回List集合
List<Element> list = document.selectNodes("//name");
for (Element element : list) {
String id = element.attributeValue("id");
String text = element.getText();
System.out.println(text);
}
//查找age标签,标签上有aaa属性的元素
List<Element> ages = document.selectNodes("//age[@aaa]");
//查找age标签,并且标签aaa=dsas
Element age =(Element) document.selectSingleNode("//age[@aaa='dsas']");
System.out.println(age.getText());
}
五、Dom4j 操作 XML 文档
1、使用 dom4j 解析 xml
步骤:
(1)得到 document 对象
SAXReader reader = new SAXReader();
Document document = reader.read(url);
(2)Document 接口的父接口是 Node
如果在 Document 里面找不到想要的方法,可以去 Node 里面找。
Document 常用方法:
DocumentType docType = document.getDocType(); //获取文档类型
String xmlEncoding = document.getXMLEncoding(); //获取文件编码
Document document1 = document.getDocument(); //获取整个文档
String name = document.getName(); //获取文档名字
String path = document.getPath(); //获取文档路径
Element rootElement = document.getRootElement(); //获取根节点,返回 Element 对象
(3)Element 也是一个接口,父接口是 Node
Element 常用方法:
getParent(); 获取父节点
element(标签的名称): 获取标签下面是 这个标签名 的 第一个 子标签
elements(): 获取标签下面的 所有 一层子标签
elements(标签的名称):获取标签下面是 这个标签名 的 所有 一层子标签
(4)案例
@Test
//功能:解析xml文档
public void test() throws DocumentException {
//1、得到document对象
SAXReader reader = new SAXReader();
Document document = reader.read("src/books.xml");
//2、获取根元素,返回 Element 对象
Element root = document.getRootElement();
//element(标签的名称)获取标签下面是 这个标签名 的 所有 一层子标签
List<Element> books = root.elements("book");
for (Element book : books) {
System.out.println("book.asXML() = " + book.asXML());
}
//elements() 获取标签下面的 所有 一层子标签。
List<Element> elements = root.elements();
for (Element element : elements) {
System.out.println("element.asXML() = " + element.asXML());
}
//element(标签的名称) 获取标签下面是 这个标签名 的 第一个 子标签
Element book = root.element("book");
System.out.println("book.asXML() = " + book.asXML());
// getParent() 获取父节点
Element parent = book.getParent();
System.out.println("parent.asXML() = " + parent.asXML());
}
2、使用 dom4j 查询 xml
步骤:
- 创建解析器,得到 document 对象
- 得到根节点 getRootElement() 返回 Element
- 得到需要的标签,根据需要返回一个或多个(List 集合)
- 通过 getText() 方法获取里面的值或使用 elementText(标签名) 获取里面的值
Demo:
@Test
//功能:查询
//需求:查询所有元素里面的值
public void test() throws DocumentException {
//1、创建解析器,得到document对象
SAXReader reader = new SAXReader();
Document document = reader.read("src/books.xml");
//2、获取根元素,返回 Element 对象
Element root = document.getRootElement();
//3、获取根节点下面一层的所有 book 元素
List<Element> book = root.elements("book");
for (Element element : book) {
//1)得到 book 下面的 name元素
Element name = element.element("name");
//得到 name 里面的文本值
String nameText = name.getText();
//2)elementText(标签名) 直接获取指定标签名的文本内容
String price = element.elementText("price");
String author = element.elementText("author");
System.out.println("name=" + nameText + ";price=" + price + ";author=" + author);
}
}
3、使用 dom4j 实现添加操作
步骤:
- 创建解析器,得到 document 对象
- 获取根元素,返回 Element 对象
- 获取第一个 book 节点
- 在 book 节点下面添加元素,并给元素添加文本内容或属性
- 回写 xml
Demo:
@Test
//功能:添加
//需求:在第一个 book 末尾添加 <sex>nv</sex> 元素
public void test06() throws DocumentException, IOException {
//1、创建解析器,得到document对象
SAXReader reader = new SAXReader();
Document document = reader.read("src/books.xml");
//2、获取根元素,返回 Element 对象
Element root = document.getRootElement();
//3、获取第一个 book节点
Element book = root.element("book");
//4、在 book节点下面添加元素
Element sex = book.addElement("sex");
//5、在添加完成之后给元素添加文本内容
sex.setText("nv");
//添加属性和值
sex.setAttributeValue("abc","abc");
//6、回写 xml(以上的操作都是在对内存中的Document对象的处理,必须回写到硬盘上才能更改)
//OutputFormat format = OutputFormat.createCompactFormat(); //压缩格式的,不便于阅读
OutputFormat format = OutputFormat.createPrettyPrint(); //可以有缩进的效果
XMLWriter xmlWriter = new XMLWriter(new FileOutputStream("src/books.xml"),format);
xmlWriter.write(document);
xmlWriter.close();
}
4、使用 dom4j 实现在特定位置添加元素
步骤:
- 创建解析器,得到 document 对象
- 获取根元素,返回 Element 对象
- 获取第一个 book 节点
- 获取 book 下面的所有的元素,返回一个 List
- 使用 DocumentHelper 类方法 createElement 创建标签,使用 setText(文本) 方法,添加文本,使用 setAttributeValue(s1,s2) 添加属性
- 添加到 list 集合中:add(int index, E element) 第一个参数是位置,下标,从 0 开始,第二个参数是要添加的元素
- 回写 xml
Demo:
@Test
//功能:在特定位置添加元素
//需求:在第一个 book 下面的 author 之前添加 <addr>北京</addr>
public void test07() throws DocumentException, IOException {
//1、创建解析器,得到document对象
SAXReader reader = new SAXReader();
Document document = reader.read("src/books.xml");
//2、获取根元素,返回 Element 对象
Element root = document.getRootElement();
//3、获取第一个 book
Element book = root.element("book");
//4、获取 book 下面的所有的元素
List<Element> elements = book.elements();
//5、创建要添加的元素,使用DocumentHelper。末尾添加不用,指定位置添加要创建元素
Element addr = DocumentHelper.createElement("addr");
//给 addr 下面创建文本
addr.setText("北京");
addr.setAttributeValue("abc","abc");
//6、在需要的位置添加
elements.add(2,addr);
//7、回写 xml
OutputFormat format = OutputFormat.createPrettyPrint();
XMLWriter xmlWriter = new XMLWriter(new FileOutputStream("src/books.xml"), format);
xmlWriter.write(document);
xmlWriter.close();
}
Tips: 可以对得到 document 的操作和 回写 xml 的操作,封装成方法,也可以把传递的文件路径,封装成一个常量
好处:可以提高开发速度,可以提交代码可维护性
5、使用 dom4j 实现 修改节点的操作
步骤:
- 创建解析器,得到 document 对象
- 获取根元素,返回 Element 对象
- 获取第一个 book 节点
- 获取要修改的结点,使用 setText() 方法修改内容
- 回写 xml
Demo:
@Test
//功能:修改节点
//需求:修改第一个 book 下面的 <price>19.9</price>
public void test08() throws DocumentException, IOException {
//1、创建解析器,得到document对象
SAXReader reader = new SAXReader();
Document document = reader.read("src/books.xml");
//2、获取根元素,返回 Element 对象
Element root = document.getRootElement();
//3、获取第一个 book
Element book = root.element("book");
//4、获取第一个 book 下面的 price
Element price = book.element("price");
//5、修改内容
price.setText("19.9");
//6、回写 xml
OutputFormat format = OutputFormat.createPrettyPrint();
XMLWriter xmlWriter = new XMLWriter(new FileOutputStream("src/books.xml"), format);
xmlWriter.write(document);
xmlWriter.close();
}
6、使用 dom4j 实现 删除节点的操作
步骤:
- 创建解析器,得到 document 对象
- 获取根元素,返回 Element 对象
- 获取第一个 book 节点
- 获取要删除的结点和它的父节点,使用父节点的 remove(元素) 方法删除节点
- 回写 xml
Demo:
@Test
//功能:删除节点
//需求:修改第一个 book 下面的 <addr abc="abc">北京</addr>
public void test09() throws DocumentException, IOException {
//1、创建解析器,得到document对象
SAXReader reader = new SAXReader();
Document document = reader.read("src/books.xml");
//2、获取根元素,返回 Element 对象
Element root = document.getRootElement();
//3、获取第一个 book
Element book = root.element("book");
//4、获取第一个 book 下面的 addr 元素
Element addr = book.element("addr");
//5、
//book.remove(addr); book 为 addr的父节点,可直接获取
//或者使用 getParent() 方法获取父节点,然后再删除
Element parent = addr.getParent();
boolean flag = parent.remove(addr);
System.out.println(flag);
//6、回写 xml
OutputFormat format = OutputFormat.createPrettyPrint();
XMLWriter xmlWriter = new XMLWriter(new FileOutputStream("src/books.xml"), format);
xmlWriter.write(document);
xmlWriter.close();
}
7、使用 dom4j 获取属性的操作
步骤:
- 创建解析器,得到 document 对象
- 获取根元素,返回 Element 对象
- 获取第一个 book 节点
- 使用 attributeValue(属性名) 获取属性值
Demo:
@Test
//功能:获取属性的值
//需求:获取第一个 book 中的属性 sn 的值
public void test10() throws DocumentException {
//1、创建解析器,得到document对象
SAXReader reader = new SAXReader();
Document document = reader.read("src/books.xml");
//2、获取根元素,返回 Element 对象
Element root = document.getRootElement();
//3、获取第一个 book
Element book = root.element("book");
//4、获取 book 中属性值,里面的参数是属性名称
String sn = book.attributeValue("sn");
System.out.println("sn = " + sn);
}
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· [.NET]调用本地 Deepseek 模型
· 一个费力不讨好的项目,让我损失了近一半的绩效!
· .NET Core 托管堆内存泄露/CPU异常的常见思路
· PostgreSQL 和 SQL Server 在统计信息维护中的关键差异
· C++代码改造为UTF-8编码问题的总结
· 一个费力不讨好的项目,让我损失了近一半的绩效!
· 清华大学推出第四讲使用 DeepSeek + DeepResearch 让科研像聊天一样简单!
· 实操Deepseek接入个人知识库
· CSnakes vs Python.NET:高效嵌入与灵活互通的跨语言方案对比
· Plotly.NET 一个为 .NET 打造的强大开源交互式图表库