首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計疑難解答

dom4j 解析 Spring XML 完整指南:讀取、遍歷、屬性操作、新增節點、寫入檔案

     編輯:程式設計疑難解答

使用 dom4j 解析 Spring `beans.xml` 配置檔,涵蓋 `SAXReader` 讀取、`Element` 遍歷、屬性增刪改、節點新增、格式化寫入檔案的完整實戰代碼。適用於需程式化操作 Spring XML 的場景。

核心依賴

<dependency>
    <groupId>org.dom4j</groupId>
    <artifactId>dom4j</artifactId>
    <version>2.1.4</version>
</dependency>
<!-- 需相容的 JAXP 實現,如 xerces 或 JDK 內建 -->

Spring beans.xml 範例

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="https://www.springframework.org/schema/beans"
       xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="https://www.springframework.org/schema/beans
       https://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean id="userService" class="com.example.UserService">
        <property name="userDao" ref="userDao"/>
        <property name="cacheEnabled" value="true"/>
    </bean>

    <bean id="userDao" class="com.example.UserDaoImpl">
        <property name="dataSource" ref="dataSource"/>
    </bean>

    <bean id="dataSource" class="com.zaxxer.hikari.HikariDataSource" destroy-method="close">
        <property name="jdbcUrl" value="jdbc:mysql://localhost:3306/mydb"/>
        <property name="username" value="root"/>
        <property name="password" value="123456"/>
    </bean>
</beans>

1. 讀取並遍歷所有 Bean 定義

import org.dom4j.*;
import org.dom4j.io.SAXReader;
import java.io.File;
import java.util.List;

public class SpringXmlParser {
    public static void main(String[] args) throws Exception {
        // 1. 建立 SAXReader
        SAXReader reader = new SAXReader();
        // 2. 讀取檔案 -> Document
        Document document = reader.read(new File("src/main/resources/beans.xml"));
        // 3. 取得根元素
        Element root = document.getRootElement();
        // 4. 遍歷所有 bean 子元素
        List beans = root.elements("bean");
        for (Element bean : beans) {
            String id = bean.attributeValue("id");
            String clazz = bean.attributeValue("class");
            System.out.println("Bean: id=" + id + ", class=" + clazz);
            // 遍歷 property 子元素
            for (Element prop : bean.elements("property")) {
                String name = prop.attributeValue("name");
                String value = prop.attributeValue("value");
                String ref = prop.attributeValue("ref");
                System.out.println("  Property: name=" + name + 
                    (value != null ? ", value=" + value : "") +
                    (ref != null ? ", ref=" + ref : ""));
            }
        }
    }
}

2. 遞迴列印完整 XML 結構(含屬性、文字)

public static void printTree(Element node, int indent) {
    String prefix = "  ".repeat(indent);
    System.out.println(prefix + "Element: " + node.getName());
    // 列印屬性
    for (Attribute attr : node.attributes()) {
        System.out.println(prefix + "  Attr: " + attr.getName() + " = " + attr.getValue());
    }
    // 列印文字內容
    String text = node.getTextTrim();
    if (!text.isEmpty()) {
        System.out.println(prefix + "  Text: " + text);
    }
    // 遞迴子元素
    for (Element child : node.elements()) {
        printTree(child, indent + 1);
    }
}
// 呼叫
printTree(document.getRootElement(), 0);

3. 修改屬性:為 dataSource 新增 `maximumPoolSize`

public static void addProperty(Document doc) {
    Element root = doc.getRootElement();
    // 找到 id="dataSource" 的 bean
    Element dsBean = (Element) root.selectSingleNode("//bean[@id='dataSource']");
    if (dsBean != null) {
        Element prop = dsBean.addElement("property");
        prop.addAttribute("name", "maximumPoolSize");
        prop.addAttribute("value", "20");
        System.out.println("已新增 maximumPoolSize=20");
    }
}

4. 新增節點:註冊新 Bean `redisTemplate`

public static void addBean(Document doc) {
    Element root = doc.getRootElement();
    Element bean = root.addElement("bean");
    bean.addAttribute("id", "redisTemplate");
    bean.addAttribute("class", "org.springframework.data.redis.core.RedisTemplate");
    Element prop = bean.addElement("property");
    prop.addAttribute("name", "connectionFactory");
    prop.addAttribute("ref", "redisConnectionFactory");
    System.out.println("已新增 redisTemplate bean");
}

5. 格式化寫入新檔案 (UTF-8、縮排)

import org.dom4j.io.OutputFormat;
import org.dom4j.io.XMLWriter;
import java.io.FileOutputStream;
import java.io.OutputStreamWriter;

public static void writeXml(Document doc, String outPath) throws Exception {
    OutputFormat format = OutputFormat.createPrettyPrint();
    format.setEncoding("UTF-8");
    format.setIndent("  ");  // 兩空格縮排
    format.setNewlines(true);

    XMLWriter writer = new XMLWriter(
        new OutputStreamWriter(new FileOutputStream(outPath), "UTF-8"), format);
    writer.write(doc);
    writer.flush();
    writer.close();
    System.out.println("已寫入: " + outPath);
}

6. 處理命名空間 (Spring XML 預設 ns)

// Spring beans 預設命名空間 URI
String nsUri = "https://www.springframework.org/schema/beans";
// 建立 Namespace 物件
Namespace ns = Namespace.get("beans", nsUri);
// 查詢時需帶命名空間
Element root = doc.getRootElement();
List beans = root.elements(new QName("bean", nsUri));
// 或用 XPath
List beans2 = root.selectNodes("//beans:bean", 
    new org.dom4j.XPathPattern("//beans:bean").getNamespaces());

完整整合範例

public class SpringXmlDemo {
    public static void main(String[] args) throws Exception {
        SAXReader reader = new SAXReader();
        Document doc = reader.read(new File("beans.xml"));

        // 1. 列印原始結構
        printTree(doc.getRootElement(), 0);

        // 2. 修改:dataSource 新增屬性
        addProperty(doc);

        // 3. 新增:redisTemplate bean
        addBean(doc);

        // 4. 寫入新檔
        writeXml(doc, "beans-modified.xml");
    }
    // ... 上述輔助方法
}

常見坑與對策

問題對策
中文亂碼`OutputFormat.setEncoding("UTF-8")` + `OutputStreamWriter(..., "UTF-8")`
命名空間查不到元素用 `QName(name, namespaceURI)` 或 XPath 註冊前綴
寫入後 XML 宣告缺失`OutputFormat.createPrettyPrint()` 會自動輸出 ``
大檔案記憶體溢位改用 StAX (`XMLStreamReader`) 流式解析
DTD/Schema 驗證失敗`reader.setValidation(false)` 或 `reader.setEntityResolver` 忽略外部 DTD

掌握 `SAXReader.read()` → `Element.elements()/attributeValue()` → `addElement()/addAttribute()` → `XMLWriter.write()` 核心鏈路,即可靈活程式化操作 Spring XML 配置。

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