dom4j 是 Java 生態系中廣受歡迎的 XML 處理庫,API 直觀、支援 XPath、效能優異。本文示範三種解析 XML 字串的主流方式,並補充「透過 ID 直接取值」的進階技巧。
<dependency>
<groupId>org.dom4j</groupId>
<artifactId>dom4j</artifactId>
<version>2.1.4</version> <!-- 或更新版本 -->
</dependency>
適合完整 XML 字串已在記憶體中,無需額外 Reader。
import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.Attribute;
import java.util.List;
import java.util.Iterator;
public class ParseDemo1 {
public static void main(String[] args) throws Exception {
String xml = "<request>"
+ "<param name='service'>single_trade_query</param>"
+ "<param name='_input_charset'>utf-8</param>"
+ "<param name='partner'>2088001513232645</param>"
+ "<param name='out_trade_no'>20090422577264</param>"
+ "</request>";
Document doc = DocumentHelper.parseText(xml);
Element root = doc.getRootElement();
for (Iterator<Element> it = root.elementIterator(); it.hasNext(); ) {
Element el = it.next();
for (Attribute attr : el.attributes()) {
if ("service".equals(attr.getText())) {
System.out.println(el.getName() + " : " + el.getTextTrim());
}
}
}
}
}
適合大型 XML 或需指定編碼、處理 DTD/Schema 驗證場景。
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.xml.sax.InputSource;
import java.io.StringReader;
import java.util.List;
import java.util.Iterator;
public class ParseDemo2 {
public static void main(String[] args) throws Exception {
String xml = "<servlet>"
+ "<description></description>"
+ "<display-name>TestServlet</display-name>"
+ "<servlet-name>TestServlet</servlet-name>"
+ "<servlet-class>test.TestServlet</servlet-class>"
+ "</servlet>";
SAXReader reader = new SAXReader();
// 可設定編碼、驗證、EntityResolver 等
reader.setEncoding("UTF-8");
InputSource source = new InputSource(new StringReader(xml));
Document doc = reader.read(source);
Element root = doc.getRootElement();
for (Iterator<Element> it = root.elementIterator(); it.hasNext(); ) {
Element el = it.next();
System.out.println(el.getName() + " : " + el.getTextTrim());
}
}
}
關鍵限制: 屬性名**必須為大寫 `ID`**,小寫 `id` 會被視為普通屬性,無法透過 elementByID() 索引。
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.xml.sax.InputSource;
import java.io.StringReader;
public class ParseDemo3 {
public static void main(String[] args) throws Exception {
String xml = "<request>"
+ "<param name='service' ID='tt'>single_trade_query</param>"
+ "<param name='_input_charset'>utf-8</param>"
+ "</request>";
SAXReader reader = new SAXReader();
Document doc = reader.read(new InputSource(new StringReader(xml)));
// 兩種方式皆可取得同一元素
Element byDoc = doc.elementByID("tt");
Element byRoot = doc.getRootElement().elementByID("tt");
System.out.println("doc.elementByID: " + byDoc.getTextTrim());
System.out.println("root.elementByID: " + byRoot.getTextTrim());
}
}
| 場景 | 推薦方式 | 理由 |
|---|---|---|
| 小型 XML 字串、一次性解析 | DocumentHelper.parseText | 程式碼最少、無需建立 Reader |
| 大型 XML、需串流、指定編碼、關閉 DTD 驗證 | SAXReader + InputSource | 記憶體友善、可精細控制解析行為 |
| 頻繁依 ID 查詢特定節點 | SAXReader + elementByID | O(1) 定位,避免遍歷 |
root.element(new QName("localName", "namespaceURI")) 或配合 XPath。reader.setFeature("https://apache.org/xml/features/disallow-doctype-decl", true)。InputSource.setEncoding() 與實際編碼一致。dom4j 以靈活的 DOM 風格 API 與 XPath 支援,成為 Java XML 處理的經典選擇。掌握上述三種解析入口與 ID 索引技巧,可覆蓋 90% 以上的實務場景。