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

Java 更新 XML 文檔的四種主流方法對比與最佳實踐

     編輯:關於JSP

背景

JAXP (Java API for XML Processing) 是 Java 處理 XML 的標準 API,支援 DOM、SAX、XSLT,通過 Pluggability Layer 解耦具體解析器 (Xerces、Crimson) 與 XSLT 處理器 (Xalan)。常見困惑:DOM 樹內存修改後,如何同步持久化到原 XML 文件?JAXP 本身無直接「保存」方法,需借助特定實現或 XSLT 引擎輸出。

四種方法對比

方法一:手動遍歷 DOM 寫入文件 (最原始)

  • 遞歸遍歷 DOM 節點,逐個寫入 FileOutputStream。
  • 極其繁瑣、易錯、需自行處理轉義、編碼、格式化。
  • 僅適用於開發自定義 XML 解析器,業務開發**強烈不推薦**。

方法二:Apache Crimson 專有 XmlDocument.write() (已過時)

// 需依賴 crimson.jar
import org.apache.crimson.tree.XmlDocument;

DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder parser = factory.newDocumentBuilder();
Document doc = parser.parse("user.xml");

// 修改 DOM...
Element newEl = doc.createElement("fancy");
doc.getDocumentElement().appendChild(newEl);

// 強轉調用專有方法
((XmlDocument) doc).write(new FileOutputStream("xuser1.xml")); // 默認 UTF-8
// 或指定編碼
((XmlDocument) doc).write(new OutputStreamWriter(new FileOutputStream("xuser1.xml"), "GB2312"));
  • 優點:代碼極簡,直接持久化。
  • 缺點:綁定 Crimson 實現 (JAXP 1.2+ 已切換 Xerces/Xalan),高版本 JAXP/Java XML Pack/JWSDP **不再內置 Crimson**,移植性極差;性能較低。
  • 現狀:僅適用於老舊項目維護,新項目**禁用**。

方法三:JAXP 標準 Transformer (XSLT 引擎輸出) —— **推薦標準做法**

import javax.xml.transform.*;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import java.io.File;

// 修改後的 DOM Document 對象
DOMSource source = new DOMSource(doc);
StreamResult result = new StreamResult(new File("output.xml"));

TransformerFactory tf = TransformerFactory.newInstance();
Transformer transformer = tf.newTransformer();

// 關鍵:設置輸出屬性 (編碼、縮進、聲明等)
Properties props = transformer.getOutputProperties();
props.setProperty(OutputKeys.ENCODING, "GB2312");      // 解決中文亂碼
props.setProperty(OutputKeys.INDENT, "yes");           // 美化縮進
props.setProperty(OutputKeys.OMIT_XML_DECLARATION, "no"); // 保留 XML 聲明
transformer.setOutputProperties(props);

// 執行轉換 (無 XSLT 樣式表時為身份轉換,即原樣輸出)
transformer.transform(source, result);

OutputKeys 常用屬性

屬性常量典型值作用
METHODxml / html / text輸出格式
VERSION1.0 / 4.0規範版本
ENCODINGUTF-8 / GB2312字符編碼
OMIT_XML_DECLARATIONyes / no是否省略 <?xml ...?>
INDENTyes / no是否自動縮進
MEDIA_TYPEtext/xml 等MIME 類型
  • 優點:JAXP 標準 API,實現無關 (Xerces/Xalan/Crimson 均支持);靈活控制輸出格式;可輸出至任意 Result (文件、流、DOM、SAX 事件流)。
  • 缺點:大文檔內存壓力大 (需完整 DOM 树)。

方法四:Xalan 專有 Serializer (方法三變體)

  • 流程:DOM → Transformer → DOMResult → SerializerFactory.getSerializer() → 序列化輸出流。
  • 引入序列化器,適合大量文檔修改/輸出場景。
  • 缺點:需重複設置 Transformer 與 Serializer 兩套屬性;依賴 Xalan/Xerces,通用性較差;代碼繁瑣。
  • 適用:高性能批量序列化場景,且已鎖定 Xalan 技術棧。

總結與選型建議

方法通用性易用性格式控制性能推薦指數
手動遍歷高極低自行實現低⭐ (僅教學/造輪子)
Crimson XmlDocument極低高弱低⭐⭐ (僅舊項目維護)
Transformer (標準)高高強中⭐⭐⭐⭐⭐ 首選
Xalan Serializer中中強高 (批量)⭐⭐⭐ (特定場景)

其他替代方案 (補充)

  • JDOM / DOM4J:更友好的 Java 原生 DOM API,提供 XMLOutputter 直接輸出,代碼更簡潔。
  • Castor / JAXB:數據綁定框架,對象樹 marshal() 直接生成 XML。
  • StAX (JSR-173):流式寫入 (XMLStreamWriter),超大文檔低內存首選。

最佳實踐清單

  1. **首選標準 Transformer**,設置 OutputKeys.ENCODING、INDENT 等屬性。
  2. 大文檔 (>50MB) 改用 StAX 流式寫入 或 JDOM/DOM4J。
  3. 頻繁修改同一文檔,考慮 數據綁定 (JAXB) 或 數據庫 XMLType 替代文件系統。
  4. 輸出前校驗 XML 合法性 (Schema/DTD),避免生成損壞文件。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved