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

Java 遞迴遍歷 XML 完整實作:基於 DOM4J 的通用解析器

     編輯:Java 相關知識

需求場景

建立通用 XML 遞迴遍歷基礎元件,提取所有元素節點的 XPath 路徑與文字值,為複雜解析邏輯奠基。採用 DOM4J 庫實作,支援屬性、命名空間、混合內容等實際場景。

核心實作程式碼

import org.dom4j.*;
import java.util.*;

public class XmlTest {
    private static List<Leaf> elemList = new ArrayList<>();
    private static String srcXml = "\n" +
        "\n" +
        " \n" +
        "  某人\n" +
        "  \n" +
        "   \n" +
        "    10002\n" +
        "    西安市太白路\n" +
        "   \n" +
        "   10002空ID節點啊\n" +
        "   10002空ID節點啊\n" +
        "   西安市太白路2\n" +
        "  \n" +
        " \n" +
        " ASDF\n" +
        "";

    public static void main(String[] args) throws DocumentException {
        XmlTest test = new XmlTest();
        Element root = test.getRootElement();
        test.getElementList(root);
        String result = test.getListString(elemList);
        System.out.println("-----------原XML內容------------");
        System.out.println(srcXml);
        System.out.println("-----------解析結果------------");
        System.out.println(result);
    }

    public Element getRootElement() throws DocumentException {
        return DocumentHelper.parseText(srcXml).getRootElement();
    }

    // 遞迴遍歷核心邏輯
    public void getElementList(Element element) {
        List elements = element.elements();
        if (elements.isEmpty()) {
            // 葉子節點:記錄 XPath 與文字值
            elemList.add(new Leaf(element.getPath(), element.getTextTrim()));
        } else {
            // 非葉子節點:遞迴處理子元素
            for (Iterator it = elements.iterator(); it.hasNext();) {
                getElementList((Element) it.next());
            }
        }
    }

    public String getListString(List<Leaf> list) {
        StringBuffer sb = new StringBuffer();
        for (Leaf leaf : list) {
            sb.append(leaf.getXpath()).append(" = ").append(leaf.getValue()).append("\n");
        }
        return sb.toString();
    }
}

// 資料結構:封裝 XPath 與值
class Leaf {
    private String xpath, value;
    public Leaf(String xpath, String value) { this.xpath = xpath; this.value = value; }
    public String getXpath() { return xpath; }
    public String getValue() { return value; }
    public void setXpath(String xpath) { this.xpath = xpath; }
    public void setValue(String value) { this.value = value; }
}

執行結果分析

-----------解析結果------------
/doc/person/name = 某人
/doc/person/adds/add/BS = 10002
/doc/person/adds/add/note = 西安市太白路
/doc/person/adds/add/BS = 10002
/doc/person/adds/add/note = 空ID節點啊
/doc/person/adds/add/BS = 10002
/doc/person/adds/add/note = 空ID節點啊
/doc/person/adds/add/*[name()='BS'] = 
/doc/person/adds/add/note = 西安市太白路2
/doc/other/name = ASDF

關鍵觀察與擴展方向

  • 同名同路徑節點重複:多個 <add> 產生相同 XPath,實際應用需結合索引或屬性區分(如 /add[1]/BS)
  • 命名空間處理:<BS xmlns="10001"/> 產生特殊 XPath *[name()='BS'],需針對命名空間增強解析
  • 屬性值未捕獲:當前僅提取元素文字,擴展可加入屬性遍歷(element.attributes())
  • 效能優化:大型 XML 建議改用 SAX/StAX 流式處理,避免完整 DOM 樹記憶體壓力

進階應用建議

  1. 將 Leaf 擴充為包含節點類型、屬性 Map、命名空間上下文的豐富模型
  2. 加入 XPath 索引標記([1], [2])區分同級同名元素
  3. 提供「路徑過濾」、「值轉換」、「結構驗證」等插件式擴展點
  4. 整合 Schema/XSD 驗證,確保輸入 XML 符合預期結構
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved