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

Java 解析 XML 實戰:JDOM2 輕量級 API 完整指南(含命名空間處理)

     編輯:Java 綜合教學

前言:為什麼選擇 JDOM?

Java 解析 XML 四大主流方案:DOM (樹模型、內存佔用大)、SAX (事件驅動、只讀、編碼複雜)、StAX (拉解析、流式)、JDOM (Java 原生 API、輕量、鏈式調用、支持 XPath、輸出格式化)。JDOM 2.x 專為 Java 設計,API 極其直觀,是配置文件解析、輕量級數據交換、測試數據構建的首選。

一、Maven 依賴


<dependency>
    <groupId>org.jdom</groupId>
    <artifactId>jdom2</artifactId>
    <version>2.0.6.1</version>
</dependency>
<!-- 需額外添加 JAXP 實現 (如 Xerces) 若運行環境無內置 -->

二、核心類速覽

類職責
SAXBuilder構建 Document (底層用 SAX 解析)
DocumentXML 文檔根節點
Element元素節點 (核心操作對象)
Namespace命名空間封裝
Attribute屬性節點
XPathExpressionXPath 查詢 (JDOM 2.x 核心特性)
XMLOutputter格式化輸出 XML

三、實戰解析:帶命名空間的 XML 字符串

3.1 輸入 XML (含默認命名空間)


String xml = ""
    + ""
    + "  "
    + "    1001 "
    + "    wangwei "
    + "    80 "
    + "    1001號 "
    + "  "
    + "  "
    + "    1002 "
    + "    wangwei "
    + "    80 "
    + "    1002號 "
    + "  "
    + "";

3.2 完整解析代碼


import org.jdom2.*;
import org.jdom2.input.SAXBuilder;
import org.jdom2.xpath.XPathExpression;
import org.jdom2.xpath.XPathFactory;
import org.xml.sax.InputSource;
import java.io.StringReader;
import java.util.List;

public class JDomXmlParser {
    public void parse(String xmlDoc) {
        try {
            // 1. 構建 Document
            SAXBuilder builder = new SAXBuilder();
            Document doc = builder.build(new InputSource(new StringReader(xmlDoc)));
            
            // 2. 獲取根元素及其命名空間
            Element root = doc.getRootElement();
            Namespace ns = root.getNamespace(); // 默認命名空間: https://www.fiorano.com/...
            System.out.println("根元素: " + root.getName() + ", 命名空間: " + ns.getURI());
            
            // 3. 方式一:傳統遍歷 (需顯式傳遞 Namespace)
            List<Element> rows = root.getChildren("row", ns); // 關鍵:第二個參數指定命名空間
            for (Element row : rows) {
                String id = row.getChildTextTrim("users_id", ns);
                String name = row.getChildTextTrim("users_name", ns);
                String group = row.getChildTextTrim("users_group", ns);
                String address = row.getChildTextTrim("users_address", ns);
                System.out.printf("ID: %s, Name: %s, Group: %s, Address: %s%n", id, name, group, address);
            }
            
            // 4. 方式二:XPath 查詢 (推薦,代碼簡潔、性能優、支持複雜路徑)
            XPathFactory xpf = XPathFactory.instance();
            // 編譯 XPath 表達式,註冊命名空間前綴
            XPathExpression<Element> rowExpr = xpf.compile("//ns:row", Filters.element(), null, 
                Map.of("ns", ns.getURI()));
            List<Element> xpathRows = rowExpr.evaluate(doc);
            for (Element row : xpathRows) {
                String id = row.getChildTextTrim("users_id", ns);
                // ... 同樣需傳遞 ns
            }
            
            // 5. 方式三:無命名空間 XML 簡化處理
            // 若 XML 無 xmlns,則 ns = Namespace.NO_NS,getChildren("row") 即可
            
        } catch (JDOMException | IOException e) {
            throw new RuntimeException("XML 解析失敗", e);
        }
    }
    
    public static void main(String[] args) {
        String xml = "..."; // 同上
        new JDomXmlParser().parse(xml);
    }
}

四、關鍵難點:命名空間處理詳解

  1. 默認命名空間 (xmlns="..."):無前綴但有 URI。查詢子元素必須顯式傳遞 Namespace 對象,否則匹配失敗 (因為無前綴元素默認屬於無命名空間)。
  2. 帶前綴命名空間 (xmlns:ns="..."):查詢時用 getChild("name", ns) 或 XPath 註冊前綴。
  3. 無命名空間:使用 Namespace.NO_NS 或直接調用無參重載。
  4. XPath 命名空間註冊:Map.of("prefix", uri) 傳給 compile(),表達式中用 prefix:element。

五、常用操作速查表

操作代碼示例
獲取元素文本 (去除首尾空白)element.getChildTextTrim("childName", ns)
獲取屬性值element.getAttributeValue("attrName") 或 element.getAttributeValue("attrName", ns)
獲取所有子元素element.getChildren() / element.getChildren("name", ns)
創建新元素new Element("name", ns) 或 new Element("name") (無 NS)
添加子元素parent.addContent(child)
設置元素文本element.setText("content")
格式化輸出字符串new XMLOutputter(Format.getPrettyFormat()).outputString(doc)
寫入文件new XMLOutputter(Format.getPrettyFormat()).output(doc, new FileWriter("out.xml"))

六、性能與選型建議

場景推薦方案理由
配置文件解析 (小文件、需隨機訪問)JDOM2API 友好、支持 XPath、內存可接受
大文件流式讀取 (GB 級)StAX (XMLStreamReader)常數內存、事件驅動
高性能只讀遍歷SAX / StAX無樹構建開銷
需修改/寫入 XMLJDOM2 / DOM樹模型支持隨機修改
對象序列化/反序列化JAXB / Jackson XML / XStream綁定模型,業務代碼零 XML 感知

七、避坑指南

  1. 命名空間是頭號坑:默認命名空間下,getChildren("row") 返回空列表,必須用 getChildren("row", ns)。
  2. 編碼一致性:XML 聲明 encoding="gb2312",Java 讀取字符串無編碼問題;讀取文件時 new InputStreamReader(is, "GBK") 顯式指定。
  3. 實體引用:JDOM 默認不展開外部實體 (安全),需 DTD 實體時配置 builder.setEntityResolver()。
  4. 線程安全:Document/Element 非線程安全,多線程解析各自構建 SAXBuilder 實例。

八、總結

JDOM2 以純 Java 風格 API、鏈式調用、XPath 原生支持、命名空間完整處理,成為中小型 XML 處理的最佳選擇。掌握SAXBuilder 構建、Namespace 獲取傳遞、XPath 編譯查詢、XMLOutputter 格式化輸出四大核心流程,配合避坑指南,可高效應對 95% XML 解析/生成需求。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved