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

Java DOM 解析 XML 實現學生信息增刪改查 (CRUD) 完整教程

     編輯:Java 綜合教學

Java DOM 解析 XML 實現學生信息增刪改查 (CRUD) 完整教程

DOM (Document Object Model) 將 XML 載入內存形成樹狀結構,支持隨機訪問、修改、寫回文件,適合中小型配置文件或數據存儲場景。本文通過「學生管理系統」案例,完整演示 DOM 解析、節點操作、持久化全流程。

數據文件 (student.xml)

<?xml version="1.0" encoding="UTF-8"?>
<Students>
    <student id="1">
        <name>yyh1</name>
        <age>22</age>
    </student>
    <student id="2">
        <name>ttt</name>
        <age>44</age>
    </student>
    ...
</Students>

核心工具類:DomUtils.java

package com.briup.dom;

import org.w3c.dom.Document;
import javax.xml.parsers.*;
import java.io.File;
import java.io.IOException;
import org.xml.sax.SAXException;

public class DomUtils {
    public static Document getDoc(File file) throws ParserConfigurationException, SAXException, IOException {
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        DocumentBuilder builder = factory.newDocumentBuilder();
        return builder.parse(file); // 解析為 Document 樹
    }
}

業務邏輯類:StudentManager.java

package com.briup.dom;

import org.w3c.dom.*;
import javax.xml.transform.*;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import java.io.File;
import java.util.Scanner;

public class StudentManager {
    private static final String FILE_PATH = "src/com/briup/dom/student.xml";

    public static void main(String[] args) {
        try {
            Document doc = DomUtils.getDoc(new File(FILE_PATH));
            Scanner input = new Scanner(System.in);
            
            System.out.println("=== 學生管理系統 ===");
            System.out.println("1. 添加學生");
            System.out.println("2. 刪除學生");
            System.out.println("3. 修改學生");
            System.out.print("請選擇操作 (1-3): ");
            int choice = input.nextInt();
            input.nextLine(); // 消耗換行符
            
            switch (choice) {
                case 1: addStudent(doc, input); break;
                case 2: delStudent(doc, input); break;
                case 3: updStudent(doc, input); break;
                default: System.out.println("無效選項");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    // --- 新增 ---
    private static void addStudent(Document doc, Scanner input) throws TransformerException {
        Element root = doc.getDocumentElement();
        
        System.out.print("學號: ");
        String id = input.nextLine();
        
        // 唯一性校驗
        NodeList list = doc.getElementsByTagName("student");
        for (int i = 0; i < list.getLength(); i++) {
            if (id.equals(list.item(i).getAttributes().getNamedItem("id").getNodeValue())) {
                System.out.println("學號已存在!");
                return;
            }
        }
        
        System.out.print("姓名: ");
        String name = input.nextLine();
        System.out.print("年齡: ");
        String age = input.nextLine();
        
        // 創建節點樹
        Element student = doc.createElement("student");
        student.setAttribute("id", id);
        student.appendChild(createElement(doc, "name", name));
        student.appendChild(createElement(doc, "age", age));
        root.appendChild(student);
        
        persist(doc);
        System.out.println("添加成功!");
    }

    // --- 刪除 ---
    private static void delStudent(Document doc, Scanner input) throws TransformerException {
        Element root = doc.getDocumentElement();
        System.out.print("要刪除的學號: ");
        String id = input.nextLine();
        
        NodeList list = doc.getElementsByTagName("student");
        for (int i = 0; i < list.getLength(); i++) {
            Element student = (Element) list.item(i);
            if (id.equals(student.getAttribute("id"))) {
                root.removeChild(student);
                persist(doc);
                System.out.println("刪除成功!");
                return;
            }
        }
        System.out.println("未找到該學生。");
    }

    // --- 修改 ---
    private static void updStudent(Document doc, Scanner input) throws TransformerException {
        System.out.print("要修改的學號: ");
        String id = input.nextLine();
        
        NodeList list = doc.getElementsByTagName("student");
        for (int i = 0; i < list.getLength(); i++) {
            Element student = (Element) list.item(i);
            if (id.equals(student.getAttribute("id"))) {
                System.out.print("新姓名: ");
                String name = input.nextLine();
                System.out.print("新年齡: ");
                String age = input.nextLine();
                
                // 更新子節點文本
                NodeList children = student.getChildNodes();
                for (int j = 0; j < children.getLength(); j++) {
                    Node node = children.item(j);
                    if ("name".equals(node.getNodeName())) {
                        node.setTextContent(name);
                    } else if ("age".equals(node.getNodeName())) {
                        node.setTextContent(age);
                    }
                }
                persist(doc);
                System.out.println("修改成功!");
                return;
            }
        }
        System.out.println("未找到該學生。");
    }

    // --- 輔助方法 ---
    private static Element createElement(Document doc, String tag, String text) {
        Element e = doc.createElement(tag);
        e.setTextContent(text);
        return e;
    }

    private static void persist(Document doc) throws TransformerException {
        TransformerFactory factory = TransformerFactory.newInstance();
        Transformer transformer = factory.newTransformer();
        transformer.setOutputProperty(OutputKeys.INDENT, "yes"); // 格式化輸出
        transformer.transform(new DOMSource(doc), new StreamResult(new File(FILE_PATH)));
    }
}

關鍵 API 對照表

操作 核心方法 說明
創建元素 doc.createElement("tag") 創建新節點
設置屬性 element.setAttribute("id", "1") 設置 XML 屬性
設置文本 element.setTextContent("value") 替換所有子文本節點
追加子節點 parent.appendChild(child) 構建樹結構
刪除節點 parent.removeChild(child) 從樹中移除
查找節點 doc.getElementsByTagName("tag") 返回 NodeList,支持遍歷
持久化 Transformer.transform(DOMSource, StreamResult) 將內存樹寫回文件

DOM vs SAX vs Pull 選型建議

  • DOM:文件較小 (<10MB)、需頻繁修改、隨機訪問 → 本案例適用。
  • SAX:大文件、單次順序讀取、內存敏感、不需修改。
  • Pull (XmlPullParser):Android 推薦、流式、可控性強、適合移動端。

常見坑點提醒

  1. 路徑問題:FILE_PATH 需相對項目根目錄或使用絕對路徑,IDEA 運行時工作目錄為項目根目錄。
  2. 編碼一致:XML 聲明 encoding="UTF-8"、讀寫均用 UTF-8,避免中文亂碼。
  3. 格式化輸出:transformer.setOutputProperty(OutputKeys.INDENT, "yes") 保持 XML 可讀性。
  4. 併發安全:DOM 非線程安全,多線程環境需加鎖或使用線程局部變量。

掌握 DOM CRUD,輕鬆應對配置文件管理、小型數據存儲等場景。

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