Dom4j 是基於 Java 集合框架的開源 XML 操作庫,完整支持 DOM、SAX、JAXP,提供優雅的鏈式 API 與 XPath 查詢。官網:dom4j.org,SourceForge 下載最新版(1.6.1+)。核心依賴:dom4j-x.x.jar + jaxen-x.x.jar(XPath 引擎)。
所有節點接口繼承自 Node:
Document:文檔根Element:元素節點(可含屬性、子元素、文本)Attribute:屬性節點Text / CDATA / Comment:文本類節點Branch:可包含子節點的父接口(Document、Element 實現)import org.dom4j.*;
import org.dom4j.io.*;
import java.io.*;
import java.util.*;
public class Dom4jDemo {
/** 1. 創建 XML 文檔 */
public boolean createXML(String fileName) {
try {
Document doc = DocumentHelper.createDocument();
Element students = doc.addElement("students");
students.addComment("This is a test for dom4j");
// 學生 1
Element stu1 = students.addElement("student");
stu1.addAttribute("value", "god");
stu1.addElement("name").setText("finina");
stu1.addElement("age").setText("25");
stu1.addElement("sex").setText("male");
// 學生 2
Element stu2 = students.addElement("student");
stu2.addAttribute("value", "cat");
stu2.addElement("name").setText("fly");
stu2.addElement("age").setText("17");
stu2.addElement("sex").setText("female");
// 團隊信息
students.addElement("team").addText("05093A");
// 格式化輸出(關鍵:設置編碼避免中文亂碼)
OutputFormat format = OutputFormat.createPrettyPrint();
format.setEncoding("GBK"); // 或 UTF-8
XMLWriter writer = new XMLWriter(new FileWriter(fileName), format);
writer.write(doc);
writer.close();
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/** 2. 修改 XML:屬性更新、節點增刪、文本替換 */
public boolean modifyXML(String oldFile, String newFile) {
try {
SAXReader reader = new SAXReader();
Document doc = reader.read(new File(oldFile));
// ① 將所有 student@value="god" 改為 "king"
for (Attribute attr : (List<Attribute>) doc.selectNodes("/students/student/@value")) {
if ("god".equals(attr.getValue())) attr.setValue("king");
}
// ② 修改 team 文本,並添加子元素 teacher
Element team = (Element) doc.selectSingleNode("/students/team");
if (team != null) {
team.setText("05084A");
Element teacher = team.addElement("teacher");
teacher.setText("godfather");
teacher.addAttribute("skill", "programme");
}
// ③ 刪除 age=17 的 age 節點(保護未成年人隱私)
for (Element stu : (List<Element>) doc.selectNodes("/students/student")) {
Element age = stu.element("age");
if (age != null && "17".equals(age.getText())) {
stu.remove(age);
}
}
// 保存修改
OutputFormat format = OutputFormat.createPrettyPrint();
format.setEncoding("GBK");
XMLWriter writer = new XMLWriter(new FileWriter(newFile), format);
writer.write(doc);
writer.close();
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/** 3. 讀取並遞歸遍歷 XML */
public void readXML(String fileName) {
try {
SAXReader reader = new SAXReader();
Document doc = reader.read(new File(fileName));
traverse(doc.getRootElement());
} catch (Exception e) {
e.printStackTrace();
}
}
private void traverse(Element element) {
for (Iterator> it = element.elementIterator(); it.hasNext(); ) {
Element el = (Element) it.next();
if (!el.getTextTrim().isEmpty()) {
System.out.println(el.getName() + " 節點的值是 " + el.getText());
} else {
System.out.println(el.getName() + " 節點");
}
for (Iterator> ait = el.attributeIterator(); ait.hasNext(); ) {
Attribute attr = (Attribute) ait.next();
System.out.println(el.getName() + " 節點的屬性 " + attr.getName() + " 的值是 " + attr.getValue());
}
traverse(el); // 遞歸子元素
}
}
/** 主方法演示 */
public static void main(String[] args) {
Dom4jDemo demo = new Dom4jDemo();
String file = "dom4jDemo.xml";
String newFile = "new_dom4jDemo.xml";
System.out.println("創建 " + file + " ...");
if (demo.createXML(file)) System.out.println("創建成功!");
System.out.println("修改並另存為 " + newFile + " ...");
if (demo.modifyXML(file, newFile)) System.out.println("修改成功!");
System.out.println("讀取原文件:");
demo.readXML(file);
System.out.println("讀取新文件:");
demo.readXML(newFile);
}
}
SAXReader:事件驅動,適合大文件(默認)。DOMReader:樹模型,適合需隨機訪問場景。File、InputStream、URL、Reader 多種來源。elementIterator() / attributeIterator(),最常用。nodeCount() + node(i),適合深度處理。Visitor 接口(或繼承 VisitorSupport),調用 node.accept(visitor) 自動遍歷全樹,代碼最乾淨。List nodes = doc.selectNodes("//foo/bar"); // 多節點
Node node = doc.selectSingleNode("//foo/bar/author"); // 單節點
String name = node.valueOf("@name"); // 直接取屬性值
// 實例:提取 XHTML 所有鏈接
List links = doc.selectNodes("//a/@href");
// XML → String
String xml = document.asXML();
// String → XML
Document doc = DocumentHelper.parseText("James ");
TransformerFactory factory = TransformerFactory.newInstance();
Transformer transformer = factory.newTransformer(new StreamSource(stylesheet));
DocumentSource source = new DocumentSource(document);
DocumentResult result = new DocumentResult();
transformer.transform(source, result);
Document transformed = result.getDocument();
必須設置編碼,否則中文輸出亂碼或無法解析:
OutputFormat format = OutputFormat.createPrettyPrint(); // 縮進美化
// OutputFormat format = OutputFormat.createCompactFormat(); // 壓縮無換行
format.setEncoding("GBK"); // 或 UTF-8, ISO-8859-1
XMLWriter writer = new XMLWriter(new FileWriter(file), format);
writer.write(document);
SAXReader + ElementHandler 流式處理,避免 DOM 模型佔用大量內存。NamespaceContext。Document 非線程安全,多線程環境下勿共享實例。