| 解析器 | 模型 | 特點 | 適用場景 |
|---|---|---|---|
| DOM (W3C) | 樹模型 | 全量加載內存、隨機訪問、可修改 | 小文件、需頻繁增刪改 |
| SAX | 事件流 | 流式、只讀、低內存 | 大文件、單次遍歷 |
| JDOM | 樹模型 | Java 原生 API、輕量 | 中小文件、偏好原生風格 |
| DOM4J | 樹模型 | 功能最全、XPath、性能優、Hibernate/JAXM 採用 | 企業級首選 |
public class DomHandler {
public String createXml() throws Exception {
DocumentBuilderFactory f = DocumentBuilderFactory.newInstance();
DocumentBuilder b = f.newDocumentBuilder();
Document doc = b.newDocument();
doc.setXmlVersion("1.0");
Element root = doc.createElement("root");
doc.appendChild(root);
Element phone = doc.createElement("TelePhone");
root.appendChild(phone);
addType(doc, phone, "nokia", "599", "CMCC");
addType(doc, phone, "xiaomi", "699", "ChinaNet");
// 輸出字符串
TransformerFactory tf = TransformerFactory.newInstance();
Transformer t = tf.newTransformer();
StringWriter sw = new StringWriter();
t.transform(new DOMSource(doc), new StreamResult(sw));
String xml = sw.toString();
// 寫文件
t.transform(new DOMSource(doc), new StreamResult(new File("phone.xml")));
return xml;
}
private void addType(Document doc, Element parent, String name, String price, String op) {
Element type = doc.createElement("type");
type.setAttribute("name", name);
Element p = doc.createElement("price"); p.setTextContent(price); type.appendChild(p);
Element o = doc.createElement("operator"); o.setTextContent(op); type.appendChild(o);
parent.appendChild(type);
}
public void parseXml(String xml) throws Exception {
DocumentBuilderFactory f = DocumentBuilderFactory.newInstance();
DocumentBuilder b = f.newDocumentBuilder();
Document doc = b.parse(new InputSource(new StringReader(xml)));
NodeList types = doc.getElementsByTagName("type");
for (int i = 0; i < types.getLength(); i++) {
Element e = (Element) types.item(i);
System.out.println("Phone: " + e.getAttribute("name"));
System.out.println(" Price: " + e.getElementsByTagName("price").item(0).getTextContent());
System.out.println(" Operator: " + e.getElementsByTagName("operator").item(0).getTextContent());
}
}
}
public class Dom4jHandler {
public String createXml() {
Document doc = DocumentHelper.createDocument();
Element root = doc.addElement("root");
Element phone = root.addElement("TelePhone");
addType(phone, "nokia", "599", "CMCC");
addType(phone, "xiaomi", "699", "ChinaNet");
// 格式化輸出字符串
OutputFormat fmt = OutputFormat.createPrettyPrint();
fmt.setEncoding("UTF-8");
StringWriter sw = new StringWriter();
new XMLWriter(sw, fmt).write(doc);
return sw.toString();
}
private void addType(Element parent, String name, String price, String op) {
Element type = parent.addElement("type").addAttribute("name", name);
type.addElement("price").addText(price);
type.addElement("operator").addText(op);
}
public void parseXml(String xml) throws DocumentException {
SAXReader reader = new SAXReader();
Document doc = reader.read(new InputSource(new StringReader(xml)));
// 普通遍歷
for (Element type : (List<Element>) doc.selectNodes("/root/TelePhone/type")) {
System.out.println("Phone: " + type.attributeValue("name"));
for (Element c : type.elements()) {
System.out.println(" " + c.getName() + ": " + c.getText());
}
}
}
public void parseXmlByXPath(String xml) throws DocumentException {
SAXReader reader = new SAXReader();
Document doc = reader.read(new InputSource(new StringReader(xml)));
// XPath 精準定位
for (Element type : (List<Element>) doc.selectNodes("/root/TelePhone/type")) {
System.out.println("Phone: " + type.attributeValue("name"));
for (Element c : (List<Element>) type.selectNodes("./*")) {
System.out.println(" " + c.getName() + ": " + c.getText());
}
}
}
}
public class XpathHandler {
public void parse(String xml) throws Exception {
DocumentBuilderFactory f = DocumentBuilderFactory.newInstance();
DocumentBuilder b = f.newDocumentBuilder();
Document doc = b.parse(new InputSource(new StringReader(xml)));
XPathFactory xf = XPathFactory.newInstance();
XPath xpath = xf.newXPath();
XPathExpression expr = xpath.compile("/root/TelePhone/type");
NodeList types = (NodeList) expr.evaluate(doc, XPathConstants.NODESET);
for (int i = 0; i < types.getLength(); i++) {
Element type = (Element) types.item(i);
System.out.println("Phone: " + type.getAttribute("name"));
NodeList props = (NodeList) xpath.compile("./*").evaluate(type, XPathConstants.NODESET);
for (int j = 0; j < props.getLength(); j++) {
Element p = (Element) props.item(j);
System.out.println(" " + p.getTagName() + ": " + p.getTextContent());
}
}
}
}
<dependency>
<groupId>org.dom4j</groupId>
<artifactId>dom4j</artifactId>
<version>2.1.4</version>
</dependency>
<dependency>
<groupId>jaxen</groupId> <!-- DOM4J XPath 依賴 -->
<artifactId>jaxen</artifactId>
<version>1.2.0</version>
</dependency>
掌握 DOM4J + XPath 組合,覆蓋 90% 企業級 XML 處理需求;理解 DOM/SAX/StAX 底層差異,面對極端場景游刃有餘。