| 維度 | DOM (JAXP) | SAX | JDOM | DOM4J |
|---|---|---|---|---|
| 解析模式 | 樹模型 (全量載入) | 事件驅動 (流式) | 樹模型 (Java 原生) | 樹模型 + 流式支援 |
| 記憶體佔用 | 高 (整檔載入) | 極低 (逐事件處理) | 中高 | 中 (支援大檔案流式) |
| 隨機訪問 | 支援 (XPath/導航) | 不支援 (單向) | 支援 | 支援 (XPath 原生) |
| 修改寫入 | 容易 | 困難 (需自建模型) | 容易 | 容易 |
| API 風格 | W3C 標準、介面導向 | 回調/Handler 模式 | 具體類、Collections 風格 | 介面+抽象類、靈活豐富 |
| 學習曲線 | 平緩 | 陡峭 | 平緩 | 中等 |
| 性能 (10MB+) | OOM 風險 | 優秀 | OOM 風險 | 優秀 (含流式) |
| 命名空間 | 支援 | 支援 | 支援 | 支援 |
| XPath 支援 | 需額外庫 | 無 | 需額外庫 | 內建 |
| 典型應用 | 小檔案、頻繁修改、配置文件 | 大檔案、單次讀取、數據提取 | 中小專案、Java 原生偏好 | 企業級、複雜 XML、Hibernate/JAXM 內部 |
假設 XML 結構:
A1234 四川省XX縣
B1234 四川省XX市
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document doc = builder.parse(new File("data.xml"));
NodeList list = doc.getElementsByTagName("VALUE");
for (int i = 0; i < list.getLength(); i++) {
Element e = (Element) list.item(i);
System.out.println(e.getElementsByTagName("NO").item(0).getTextContent());
System.out.println(e.getElementsByTagName("ADDR").item(0).getTextContent());
}
public class MyHandler extends DefaultHandler {
private String currentTag;
public void startElement(String uri, String local, String qName, Attributes attrs) {
currentTag = qName;
}
public void characters(char[] ch, int start, int length) {
String value = new String(ch, start, length);
if ("NO".equals(currentTag)) System.out.print("車牌:" + value);
if ("ADDR".equals(currentTag)) System.out.println(" 地址:" + value);
}
}
// 使用
SAXParserFactory.newInstance().newSAXParser().parse(new File("data.xml"), new MyHandler());
SAXBuilder builder = new SAXBuilder();
Document doc = builder.build(new File("data.xml"));
Element root = doc.getRootElement();
for (Element value : root.getChildren("VALUE")) {
System.out.println(value.getChildText("NO") + " " + value.getChildText("ADDR"));
}
SAXReader reader = new SAXReader();
Document doc = reader.read(new File("data.xml"));
for (Element value : doc.selectNodes("//VALUE")) {
System.out.println(value.elementText("NO") + " " + value.elementText("ADDR"));
}
// 或流式處理大檔案
reader.setFeature("https://apache.org/xml/features/nonvalidating/load-external-dtd", false);
javax.xml.xpathDOM4J 綜合性能、功能、易用性長期稱霸 Java XML 處理;但現代開發應優先考慮 JAXB 綁定 或 Jackson XML 將 XML 轉為 POJO,僅在極少數動態結構、超大檔案、舊系統維護場景下直接操作底層解析器。