XML 作為數據交換標準,Java 提供了多種解析方式。本文從原理、性能、適用場景、代碼實戰四個維度,全方位對比 DOM、SAX、JDOM、DOM4J,助你選型無憂。
| 場景 | 推薦方案 | 理由 |
|---|---|---|
| 大文件(>10MB)、內存敏感 | SAX / DOM4J 流式模式 | 不全量載入內存 |
| 小文件、需頻繁增刪改查 | DOM / JDOM | 樹結構操作便捷 |
| 需 XPath、Schema 驗證、複雜查詢 | DOM4J | 原生支持 XPath、功能最全 |
| 跨語言項目、遵循 W3C 標準 | DOM | 官方標準、多語言通用 |
| 單純讀取、一次性遍歷 | SAX | 速度最快、內存最省 |
<?xml version="1.0" encoding="GB2312"?>
<RESULT>
<VALUE>
<NO>A1234</NO>
<ADDR>XX號</ADDR>
</VALUE>
<VALUE>
<NO>B1234</NO>
<ADDR>XX組</ADDR>
</VALUE>
</RESULT>
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document doc = builder.parse(new File("data.xml"));
NodeList nl = doc.getElementsByTagName("VALUE");
for (int i = 0; i < nl.getLength(); i++) {
System.out.println("車牌:" + doc.getElementsByTagName("NO").item(i).getTextContent());
System.out.println("地址:" + doc.getElementsByTagName("ADDR").item(i).getTextContent());
}
public class SaxHandler extends DefaultHandler {
private String currentTag;
@Override
public void startElement(String uri, String localName, String qName, Attributes attrs) {
currentTag = qName;
}
@Override
public void characters(char[] ch, int start, int length) {
String value = new String(ch, start, length);
if ("NO".equals(currentTag)) System.out.print("車牌:" + value);
else if ("ADDR".equals(currentTag)) System.out.println(" 地址:" + value);
}
}
// 使用
SAXParserFactory sf = SAXParserFactory.newInstance();
SAXParser sp = sf.newSAXParser();
sp.parse(new File("data.xml"), new SaxHandler());
SAXBuilder builder = new SAXBuilder();
Document doc = builder.build(new File("data.xml"));
Element root = doc.getRootElement();
List<Element> values = root.getChildren("VALUE");
for (Element v : values) {
System.out.println("車牌:" + v.getChildText("NO"));
System.out.println("地址:" + v.getChildText("ADDR"));
}
SAXReader reader = new SAXReader();
Document doc = reader.read(new File("data.xml"));
Element root = doc.getRootElement();
for (Iterator<Element> it = root.elementIterator("VALUE"); it.hasNext(); ) {
Element v = it.next();
System.out.println("車牌:" + v.elementText("NO"));
System.out.println("地址:" + v.elementText("ADDR"));
}