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

Java XML 編程實戰:基於 DOM 解析器的學生花名冊讀寫完整範例

     編輯:Java 相關知識

前言:為什麼選 DOM?

DOM (Document Object Model) 將整個 XML 文檔載入內存形成樹狀結構,支援隨機訪問、修改、寫回,適合中小型文檔(< 50MB)的全量處理。本文以 JDK 1.3/1.4 + Apache Crimson 為環境,示範標準 JAXP API 讀寫「學生花名冊」XML,代碼兼容性強,易於遷移至 Xerces、JAXP 1.4+ 等新版本。

範例 XML 結構 (Input.xml)

<?xml version="1.0" encoding="GB2312"?>
<學生花名冊>
  <學生 性別="男">
    <姓名>李華</姓名>
    <年齡>14</年齡>
    <電話>6287555</電話>
  </學生>
  <學生 性別="男">
    <姓名>張三</姓名>
    <年齡>16</年齡>
    <電話>8273425</電話>
  </學生>
</學生花名冊>

領域模型:StudentBean

public class StudentBean {
    private String sex, name, phone;
    private int age;
    // 標準 getter/setter 省略...
}

核心工具類:XMLTest

依賴包

import java.io.*;
import java.util.*;
import javax.xml.parsers.*;
import org.w3c.dom.*;
import org.apache.crimson.tree.XmlDocument; // 僅寫入時需強轉

讀取 XML → List<StudentBean>

private void readXMLFile(String inFile) throws Exception {
    DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
    DocumentBuilder db = dbf.newDocumentBuilder();
    Document doc = db.parse(new File(inFile));

    Element root = doc.getDocumentElement(); // 學生花名冊
    NodeList students = root.getElementsByTagName("學生");

    for (int i = 0; i < students.getLength(); i++) {
        Element stuElem = (Element) students.item(i);
        StudentBean bean = new StudentBean();
        bean.setSex(stuElem.getAttribute("性別"));

        bean.setName(getSingleChildText(stuElem, "姓名"));
        bean.setAge(Integer.parseInt(getSingleChildText(stuElem, "年齡")));
        bean.setPhone(getSingleChildText(stuElem, "電話"));

        studentList.add(bean);
    }
}

// 輔助:取單一子元素文本
private String getSingleChildText(Element parent, String tagName) {
    NodeList nl = parent.getElementsByTagName(tagName);
    if (nl.getLength() == 1) {
        return ((Text) nl.item(0).getFirstChild()).getNodeValue();
    }
    return "";
}

寫入 List<StudentBean> → XML 文件

private void writeXMLFile(String outFile) throws Exception {
    DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
    DocumentBuilder db = dbf.newDocumentBuilder();
    Document doc = db.newDocument();

    Element root = doc.createElement("學生花名冊");
    doc.appendChild(root);

    for (StudentBean bean : studentList) {
        Element stu = doc.createElement("學生");
        stu.setAttribute("性別", bean.getSex());
        root.appendChild(stu);

        appendTextElement(doc, stu, "姓名", bean.getName());
        appendTextElement(doc, stu, "年齡", String.valueOf(bean.getAge()));
        appendTextElement(doc, stu, "電話", bean.getPhone());
    }

    // 關鍵:強轉為 Crimson 專有類以調用 write()
    try (FileOutputStream fos = new FileOutputStream(outFile);
         OutputStreamWriter osw = new OutputStreamWriter(fos, "GB2312")) {
        ((XmlDocument) doc).write(osw, "GB2312"); // 解決中文亂碼
    }
}

private void appendTextElement(Document doc, Element parent, String tag, String text) {
    Element e = doc.createElement(tag);
    e.appendChild(doc.createTextNode(text));
    parent.appendChild(e);
}

主程序驗證

public static void main(String[] args) throws Exception {
    XMLTest test = new XMLTest();
    test.studentList = new ArrayList<>();
    test.readXMLFile("Input.xml");
    test.writeXMLFile("Output.xml");
    System.out.println("完成!對比 Input.xml 與 Output.xml 應完全一致。");
}

關鍵技術點總結

環節要點
解析器選擇JAXP DocumentBuilderFactory 可換裝 Xerces/Crimson,無需改代碼
中文編碼讀取自動檢測;寫入必須指定 OutputStreamWriter(..., "GB2312") 並強轉 XmlDocument 調用 write(Writer, encoding)
異常處理捕獲 ParserConfigurationException、SAXException、IOException,避免資源洩漏
內存考量大文件請改用 SAX/StAX 流式處理,避免 OOM

遷移至現代 JDK (8/11/17+) 建議

  • 移除 org.apache.crimson.tree.XmlDocument 依賴,改用標準 javax.xml.transform (Transformer) 輸出,支援任意編碼與縮排。
  • 啟用 DocumentBuilderFactory.setNamespaceAware(true) 處理命名空間。
  • 若需高效能/大文件,考慮 StAX (XMLStreamReader/Writer) 或 Woodstox。

結語

DOM 模式代碼直觀、易調試,是 Java XML 入門的最佳範本。掌握「解析→樹遍歷→物件映射→樹構建→序列化」完整鏈路,即可應對絕大多數中小型 XML 業務場景。

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