Apache Commons Digester 並非一個 XML 解析器,而是對 SAX 解析器的高層封裝。它讓開發者無需深入了解 SAX 或 DOM 的解析細節,只需定義解析規則,即可將 XML 文檔直接映射為 JavaBean 對象。Digester 內部使用堆疊機制管理 XML 節點:解析到開始標籤時將對象壓入堆疊,解析完所有子節點後彈出。其核心優勢在於使用模式匹配來表達 XML 節點間的父子關係,使配置直觀且強大。
假設我們有一個 students.xml 文件,描述班級及其學生信息:
<?xml version="1.0" encoding="UTF-8" ?>
<stuClass name="fddfdf">
<student>
<name from="cn">Java Boy</name>
<course>JSP</course>
</student>
<student>
<name>Java Girl</name>
<course>EJB</course>
</student>
</stuClass>
package demo.javabean;
public class Student {
private String name;
private String from;
private String course;
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public String getFrom() { return from; }
public void setFrom(String from) { this.from = from; }
public String getCourse() { return course; }
public void setCourse(String course) { this.course = course; }
}
package demo.javabean;
import java.util.Vector;
public class StuClass {
private String name;
private Vector<Student> students = new Vector<>();
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public Vector<Student> getStudents() { return students; }
public void setStudents(Vector<Student> students) { this.students = students; }
public void addStudent(Student student) { students.add(student); }
}
以下測試類展示如何配置 Digester 規則並解析 XML:
package demo;
import org.apache.commons.digester.Digester;
import demo.javabean.StuClass;
import java.io.InputStream;
public class DigestStudents {
public static void main(String[] args) {
new DigestStudents().digest();
}
private void digest() {
try {
Digester digester = new Digester();
digester.setValidating(false);
// 1. 建立 StuClass 實例並壓入堆疊
digester.addObjectCreate("stuClass", "demo.javabean.StuClass");
// 2. 將 stuClass 節點的 name 屬性映射到 StuClass 的 name 屬性
digester.addSetProperties("stuClass", "name", "name");
// 3. 遇到 student 子節點時建立 Student 實例
digester.addObjectCreate("stuClass/student", "demo.javabean.Student");
// 4. 調用 Student.setName(),參數為 name 節點的文本內容
digester.addCallMethod("stuClass/student/name", "setName", 0);
// 5. 將 name 節點的 from 屬性映射到 Student.from
digester.addSetProperties("stuClass/student/name", "from", "from");
// 6. 將 course 節點文本內容映射到 Student.course
digester.addBeanPropertySetter("stuClass/student/course");
// 7. 當 student 解析完成,調用 StuClass.addStudent() 將其加入集合
digester.addSetNext("stuClass/student", "addStudent", "demo.javabean.Student");
// 執行解析
InputStream input = this.getClass().getClassLoader().getResourceAsStream("demo/students.xml");
StuClass ds = (StuClass) digester.parse(input);
System.out.println("班級名稱: " + ds.getName());
System.out.println("學生列表: " + ds.getStudents());
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
Digester 通過聲明式規則極大地簡化了 XML 到 Java 對象的映射工作,特別適合結構固定、層級較深的配置文件解析。掌握堆疊機制與模式匹配是靈活運用 Digester 的關鍵。