首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Java Dom4j 解析與生成 XML 實戰範例:SAXReader、XPath、格式化輸出

     編輯:Java 相關知識

前言

Dom4j 是 Java 操作 XML 的經典庫,支援 DOM 樹狀操作與 SAX 事件流解析。本文提供完整的建立、寫入、讀取、XPath 查詢範例。

1. 專案依賴

<dependency>
    <groupId>org.dom4j</groupId>
    <artifactId>dom4j</artifactId>
    <version>2.1.4</version>
</dependency>
<!-- Jaxen 用於 XPath 支援 -->
<dependency>
    <groupId>jaxen</groupId>
    <artifactId>jaxen</artifactId>
    <version>1.2.0</version>
</dependency>

2. 建立並寫入 XML

public void createXml(String filePath, String txtName) throws IOException {
    Document doc = DocumentHelper.createDocument();
    Element root = doc.addElement("root");
    
    Element head = root.addElement("head")
        .addAttribute("type", "0")
        .addAttribute("code", "3003");
    head.addElement("yhlb").setText("01");
    head.addElement("username").setText("gsyh");
    head.addElement("password").setText("zheshimima");
    
    root.addElement("body")
        .addElement("data")
        .addElement("dzwjm").setText(txtName);
    
    // 格式化輸出
    OutputFormat fmt = OutputFormat.createPrettyPrint();
    fmt.setEncoding("UTF-8");
    try (FileWriter fw = new FileWriter(filePath);
         XMLWriter xw = new XMLWriter(fw, fmt)) {
        xw.write(doc);
    }
}

3. SAXReader 解析整份文件

public String parseXml(String filePath) throws DocumentException {
    SAXReader reader = new SAXReader();
    Document doc = reader.read(new File(filePath));
    Element root = doc.getRootElement();
    
    // 迭代所有子元素
    for (Element head : root.elements()) {
        for (Element elem : head.elements()) {
            System.out.println(elem.getName() + " = " + elem.getTextTrim());
            for (Element leaf : elem.elements()) {
                System.out.println("  " + leaf.getName() + " = " + leaf.getTextTrim());
            }
        }
    }
    // 取得特定值
    return root.element("body").element("data").elementText("dzwjm");
}

4. XPath 精準查詢(推薦)

// 直接取得密碼節點
Node pwdNode = doc.selectSingleNode("//head/password");
String password = pwdNode != null ? pwdNode.getText() : "";

// 取得所有 data 節點
List<Node> dataNodes = doc.selectNodes("//body/data");
for (Node n : dataNodes) {
    System.out.println(n.getText());
}

// 命名空間處理
Map<String, String> nsMap = new HashMap<>();
nsMap.put("ns", "https://example.com/ns");
XPath xpath = DocumentHelper.createXPath("//ns:user/ns:name");
xpath.setNamespaceURIs(nsMap);

5. 大文件流式解析(避免 OOM)

SAXReader reader = new SAXReader();
reader.setValidation(false);
reader.setFeature("https://apache.org/xml/features/nonvalidating/load-external-dtd", false);

// 實作 ElementHandler 處理特定元素
reader.addHandler("/root/body/data", new ElementHandler() {
    @Override public void onStart(ElementPath path) {}
    @Override public void onEnd(ElementPath path) {
        Element data = path.getCurrent();
        String fileName = data.elementText("dzwjm");
        // 處理完立即釋放記憶體
        path.getCurrent().detach();
    }
});
reader.read(new File("large.xml"));

6. 常見問題快速解決

  • 中文亂碼:寫入時 OutputFormat.setEncoding("UTF-8"),讀取時確保檔案確實為 UTF-8。
  • 實體未宣告錯誤:關閉 DTD 驗證 reader.setFeature("...load-external-dtd", false)。
  • 預設命名空間:XPath 查詢需註冊前綴,否則無法匹配無前綴的預設命名空間。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved