添加 dom4j 依赖
你需要在你的项目中添加 dom4j 的依赖,如果你使用 Maven,只需在 pom.xml 文件中添加以下依赖:

<dependency>
<groupId>org.dom4j</groupId>
<artifactId>dom4j</artifactId>
<version>2.1.4</version> <!-- 建议使用较新版本 -->
</dependency>
如果你不使用 Maven,可以从 Maven 中央仓库 下载 JAR 文件并手动添加到项目的类路径中。
示例 XML 文件
我们将使用以下 books.xml 文件作为解析示例。
books.xml
<?xml version="1.0" encoding="UTF-8"?>
<bookstore>
<book category="children">
<title lang="en">Harry Potter</title>
<author>J.K. Rowling</author>
<year>2005</year>
<price>29.99</price>
</book>
<book category="web">
<title lang="en">Learning XML</title>
<author>Erik T. Ray</author>
<year>2003</year>
<price>39.95</price>
</book>
<book category="cooking">
<title lang="zh">Everyday Italian</title>
<author>Giada De Laurentiis</author>
<year>2005</year>
<price>30.00</price>
</book>
</bookstore>
核心解析步骤
使用 dom4j 解析 XML 通常遵循以下步骤:

- 创建 SAXReader 对象:
SAXReader是dom4j用于读取 XML 文档并构建 DOM 树的核心类。 - 读取 XML 文件:使用
SAXReader的read()方法读取 XML 文件,返回一个Document对象,代表整个 XML 文档的树形结构。 - 获取根元素:通过
Document对象的getRootElement()方法获取 XML 的根元素(<bookstore>)。 - 遍历和查询节点:使用
dom4j提供的方法(如elementIterator(),elements(),element())或 XPath 表达式来查找和遍历子元素。 - 获取节点信息:获取元素的名称、属性、文本内容等。
- 处理数据:根据获取的数据进行业务逻辑处理。
代码示例
下面是一个完整的 Java 类,演示了如何读取 books.xml 文件并打印出所有书籍的信息。
import org.dom4j.*;
import org.dom4j.io.SAXReader;
import java.io.File;
import java.util.List;
public class Dom4jParser {
public static void main(String[] args) {
try {
// 1. 创建 SAXReader 对象
SAXReader reader = new SAXReader();
// 2. 读取 XML 文件,获取 Document 对象
// 注意:请确保 books.xml 文件位于项目的根目录下,或提供正确的路径
Document document = reader.read(new File("books.xml"));
// 3. 获取根元素
Element rootElement = document.getRootElement();
System.out.println("根元素是: " + rootElement.getName());
System.out.println("----------------------------------------");
// 4. 遍历所有 <book> 元素
// 使用 elementIterator 遍历所有名为 "book" 的直接子元素
Iterator<Element> bookIterator = rootElement.elementIterator("book");
while (bookIterator.hasNext()) {
Element bookElement = bookIterator.next();
// 5. 获取元素属性
String category = bookElement.attributeValue("category");
System.out.println("书籍类别: " + category);
// 6. 获取子元素信息
// element() 方法获取第一个匹配的子元素
Element titleElement = bookElement.element("title");
Element authorElement = bookElement.element("author");
Element yearElement = bookElement.element("year");
Element priceElement = bookElement.element("price");
// 获取元素的文本内容
String title = titleElement.getText();
String author = authorElement.getText();
String year = yearElement.getText();
String price = priceElement.getText();
// 获取子元素的属性
String lang = titleElement.attributeValue("lang");
System.out.println(" - 书名: " + title + " (语言: " + lang + ")");
System.out.println(" - 作者: " + author);
System.out.println(" - 年份: " + year);
System.out.println(" - 价格: " + price);
System.out.println("----------------------------------------");
}
} catch (DocumentException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
}
代码解释:
SAXReader reader = new SAXReader();:创建解析器。reader.read(new File("books.xml"));:从文件系统加载 XML 并解析成Document对象。document.getRootElement();:获取文档的根节点<bookstore>。rootElement.elementIterator("book");:获取一个迭代器,用于遍历根元素下所有名为book的直接子元素。bookElement.attributeValue("category");:获取当前<book>元素的category属性的值。bookElement.element("title");:获取当前<book>元素下第一个名为title的子元素,Element.getText();获取元素内的文本内容("Harry Potter"),Element.attributeValue("lang");:获取<title>元素的lang属性的值。
使用 XPath 进行高级查询
dom4j 的一个强大之处在于它对 XPath 的原生支持,XPath 可以让你用更简洁、更强大的方式定位 XML 节点。
示例1:获取所有书籍的标题
// 使用 XPath 获取所有 <title> 元素
List<Node> titleNodes = document.selectNodes("//title");
for (Node node : titleNodes) {
Element titleElement = (Element) node;
System.out.println("通过 XPath 找到的书名: " + titleElement.getText());
}
//title:这是一个 XPath 表达式,表示文档中任意层级的所有title元素。
示例2:获取特定类别(category="children")的书籍信息
// 使用 XPath 获取 category 属性为 "children" 的 <book> 元素
String xpath = "//book[@category='children']";
Node node = document.selectSingleNode(xpath);
if (node != null) {
Element bookElement = (Element) node;
System.out.println("\n找到类别为 'children' 的书籍:");
System.out.println("书名: " + bookElement.element("title").getText());
System.out.println("作者: " + bookElement.element("author").getText());
}
//book[@category='children']:查找所有book元素,且其category属性的值等于'children'。selectSingleNode():只返回第一个匹配的节点。
示例3:获取价格高于 35 的书籍标题
// 获取所有 <price> 元素,并过滤其文本内容大于 35 的
List<Node> expensiveBooks = document.selectNodes("//book[price > 35]/title");
System.out.println("\n价格高于 35 的书籍标题:");
for (Node node : expensiveBooks) {
System.out.println(node.getText());
}
//book[price > 35]/title://book:查找所有book元素。[price > 35]:这是一个谓词(predicate),用于过滤book元素,条件是其子元素<price>的文本内容大于 35。/title:只返回满足条件的book元素的title子元素。
创建和修改 XML
dom4j 不仅可以解析 XML,还可以用来创建和修改 XML。
创建新 XML
import org.dom4j.DocumentHelper;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.XMLWriter;
public class CreateXml {
public static void main(String[] args) throws Exception {
// 1. 创建一个 Document 对象
Document document = DocumentHelper.createDocument();
// 2. 添加根元素
Element root = document.addElement("root");
// 3. 在根元素下添加子元素
Element child1 = root.addElement("child1").addAttribute("id", "001");
child1.setText("这是第一个子元素");
Element child2 = root.addElement("child2");
child2.addComment("这是一个注释");
// 4. 设置格式并写入文件
OutputFormat format = OutputFormat.createPrettyPrint(); // 美化输出
XMLWriter writer = new XMLWriter(new java.io.FileWriter("new_books.xml"), format);
writer.write(document);
writer.close();
System.out.println("XML 文件创建成功!");
}
}
修改现有 XML
public class ModifyXml {
public static void main(String[] args) throws Exception {
SAXReader reader = new SAXReader();
Document document = reader.read(new File("books.xml"));
// 1. 修改元素内容
// 找到第一本书的价格并修改
Node firstBookPrice = document.selectSingleNode("//book[1]/price");
if (firstBookPrice != null) {
firstBookPrice.setText("19.99"); // 价格大促销!
}
// 2. 添加新元素
// 找到最后一本书,添加一个 <pages> 元素
Node lastBook = document.selectSingleNode("//book[last()]");
if (lastBook != null) {
lastBook.addElement("pages").setText("300");
}
// 3. 删除元素
// 删除第二本书的 <year> 元素
Node secondBookYear = document.selectSingleNode("//book[2]/year");
if (secondBookYear != null) {
secondBookYear.getParent().remove(secondBookYear);
}
// 4. 保存修改
XMLWriter writer = new XMLWriter(new FileWriter("books_modified.xml"));
writer.write(document);
writer.close();
System.out.println("XML 文件修改成功!");
}
}
| 功能 | dom4j 方法/XPath |
|---|---|
| 解析 | SAXReader reader = new SAXReader();Document doc = reader.read(file); |
| 获取根元素 | Element root = doc.getRootElement(); |
| 获取元素名称 | element.getName(); |
| 获取元素文本 | element.getText(); |
| 获取元素属性 | element.attributeValue("attrName"); |
| 获取子元素 | element.element("childName"); (第一个)element.elements("childName"); (所有) |
| 遍历子元素 | element.elementIterator(); |
| XPath 查询 | document.selectNodes("//xpath"); (返回列表)document.selectSingleNode("//xpath"); (返回单个) |
| 创建元素 | parentElement.addElement("newChild"); |
| 添加属性 | element.addAttribute("name", "value"); |
| 添加文本 | element.setText("text content"); |
| 删除节点 | parentElement.remove(childElement); |
| 保存文档 | XMLWriter writer = new XMLWriter(...);writer.write(document); |
dom4j 是一个功能非常全面的 XML 处理工具,无论是简单的读取还是复杂的查询、转换,它都能高效地完成任务,掌握 dom4j 是 Java 开发者处理 XML 数据的一项重要技能。
