XML 解析器分類
| 解析器 | 類型 | 核心特點 | 適用場景 |
| DOM | 樹模型 | 全量載入內存、可隨機訪問、支持修改寫入 | 小文件、需多次訪問、需修改結構 |
| SAX | 事件流 | 流式處理、內存佔用極低、只讀、單向遍歷 | 大文件、單次遍歷、內存受限環境 |
| DOM4J | 樹模型+增強 | API 友好、XPath 支持、性能優於 DOM、靈活輸出 | 企業級開發、複雜 XML 處理、需 XPath |
| JDOM | 樹模型+簡化 | Java 原生 API、代碼量少、內部委託 SAX/DOM | 簡單場景、快速開發、不需高級特性 |
統一測試 XML
ddviplinux
m
30
1. DOM 實現 (javax.xml.parsers)
// 創建文檔
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document doc = builder.newDocument();
Element root = doc.createElement("employees");
Element emp = doc.createElement("employee");
emp.appendChild(createElement(doc, "name", "丁宏亮"));
emp.appendChild(createElement(doc, "sex", "m"));
emp.appendChild(createElement(doc, "age", "30"));
root.appendChild(emp);
doc.appendChild(root);
// 寫入文件 (Transformer)
TransformerFactory tf = TransformerFactory.newInstance();
Transformer transformer = tf.newTransformer();
transformer.setOutputProperty(OutputKeys.ENCODING, "GB2312");
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
transformer.transform(new DOMSource(doc), new StreamResult(new FileOutputStream(fileName)));
// 解析文檔
Document doc = builder.parse(fileName);
NodeList employees = doc.getChildNodes();
// 遞歸遍歷 NodeList...
2. SAX 實現 (javax.xml.parsers)
// 僅支持解析,不支持創建(需手動拼接字符串或用其他庫)
SAXParserFactory factory = SAXParserFactory.newInstance();
SAXParser parser = factory.newSAXParser();
parser.parse(new FileInputStream(fileName), new DefaultHandler() {
@Override
public void startElement(String uri, String localName, String qName, Attributes attrs) {
if ("employee".equals(qName)) System.out.println(qName);
}
@Override
public void characters(char[] ch, int start, int length) {
System.out.println(new String(ch, start, length).trim());
}
});
3. DOM4J 實現 (第三方庫,需引入依賴)
// 創建文檔
Document doc = DocumentHelper.createDocument();
Element root = doc.addElement("employees");
Element emp = root.addElement("employee");
emp.addElement("name").setText("ddvip");
emp.addElement("sex").setText("m");
emp.addElement("age").setText("29");
// 寫入
XMLWriter writer = new XMLWriter(new FileWriter(fileName));
writer.write(doc);
writer.close();
// 解析 (SAXReader)
SAXReader reader = new SAXReader();
Document doc = reader.read(new File(fileName));
Element root = doc.getRootElement();
for (Element emp : root.elements("employee")) {
for (Element node : emp.elements()) {
System.out.println(node.getName() + ":" + node.getText());
}
}
4. JDOM 實現 (第三方庫)
// 創建文檔
Element root = new Element("employees");
Document doc = new Document(root);
Element emp = new Element("employee");
emp.addContent(new Element("name").setText("ddvip"));
emp.addContent(new Element("sex").setText("m"));
emp.addContent(new Element("age").setText("23"));
root.addContent(emp);
// 寫入
XMLOutputter out = new XMLOutputter();
out.output(doc, new FileOutputStream(fileName));
// 解析
SAXBuilder builder = new SAXBuilder();
Document doc = builder.build(fileName);
Element root = doc.getRootElement();
List emps = root.getChildren("employee");
for (Element emp : emps) {
for (Element node : emp.getChildren()) {
System.out.println(node.getName() + ":" + node.getValue());
}
}
性能與選型建議
| 場景 | 推薦方案 | 理由 |
| 配置文件 (小、頻繁讀寫) | DOM4J / JDOM | API 簡潔、支持 XPath、寫入方便 |
| 大數據交換文件 (100MB+) | SAX / StAX | 流式處理、常數內存、不阻塞 GC |
| 需修改結構後輸出 | DOM / DOM4J | 樹模型支持增刪改、序列化輸出 |
| Android / 受限環境 | SAX / XmlPullParser | 無第三方依賴、內存友好 |
| 高性能並行解析 | StAX (Java 6+) | 拉取式流、可控制解析節奏、易並行 |
現代替代方案
- StAX (Streaming API for XML):Java 6+ 標準庫,拉取式流,兼具 DOM 隨機訪問靈活性與 SAX 低內存
- JAXB:對象綁定,XML ↔ Java Object 自動映射,配置驅動開發首選
- Jackson XML:JSON 庫擴展,統一數據綁定 API