Kỹ Thuật Phân Tích Cấu Trúc XML Sử Dụng DOM Parser Trong Java

Việc xử lý dữ liệu định dạng XML trên môi trường Java thường yêu cầu sử dụng bộ công cụ chuẩn của nhà phát triển. Trong đó, mô hình DOM (Document Object Model) cho phép xây dựng một cấu trúc cây đầy đủ các yếu tố của tài liệu ngay trong bộ nhớRAM, giúp truy xuất và chỉnh sửa trở nên trực quan. Để thực hiện quy trình này, Java cung cấp thư viện javax.xml.parsers.

Các bước thực thi chính

Hành động giải mã file XML cần tuân thủ một trình tự chặt chẽ nhằm đảm bảo an toàn cho luồng chạy ứng dụng:

  1. Tạo một instance của DocumentBuilderFactory bằng phương thức tĩnh newInstance().
  2. Sử dụng factory để sinh ra đối tượng DocumentBuilder, đóng vai trò là người phân tích.
  3. Công cụ phân tích sẽ nạp file XML qua hàm parse(), trả về đối tượng Document đại diện cho toàn bộ cây.
  4. Phương thức getElementsByTagName() được dùng để lọc lấy NodeList chứa các thẻ mong muốn.
  5. Vòng lặp duyệt qua NodeList, truy vấn thông tin thông qua các hàm getAttribute(), getTextContent().

Mẫu dữ liệu đầu vào

Để minh họa quy trình, giả sử chúng ta có một file cấu hình config.xml:

<?xml version="1.0" encoding="UTF-8"?>
<server-info>
    <server type="web">
        <host>localhost</host>
        <port>8080</port>
    </server>
    <server type="db">
        <host>192.168.1.10</host>
        <port>3306</port>
    </server>
</server-info>

Triển khai Giải thuật

Mã nguồn dưới đây thể hiện cách viết lớp xử lý riêng biệt, tách biệt logic lỗi exception ra khỏi phần nghiệp vụ chính. Lưu ý rằng vòng lặp điều kiện không sử dụng dấu "=" so sánh lớn hơn hoặc bằng, mà dùng nhỏ hơn để tránh tràn mảng.

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.w3c.dom.Node;

import org.xml.sax.SAXException;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import java.io.File;
import java.io.IOException;

public class ConfigParserDemo {

    public static void loadConfiguration(String pathToXml) {
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        
        try {
            // Tạo builder để parse document
            DocumentBuilder builder = factory.newDocumentBuilder();
            
            // Load file từ thư mục gốc hoặc đường dẫn tuyệt đối
            Document xmlDoc = builder.parse(new File(pathToXml));
            
            // Chuyển đổi kiểu dữ liệu sang chuẩn DOM
            xmlDoc.getDocumentElement().normalize();

            // Lấy danh sách các node 'server'
            NodeList serverList = xmlDoc.getElementsByTagName("server");
            
            System.out.println("Tổng số server được cấu hình: " + serverList.getLength());

            // Vòng lặp xử lý từng node server
            for (int i = 0; i < serverList.getLength(); i++) {
                Node currentNode = serverList.item(i);
                
                // Ép kiểu sang Element để gọi các method cụ thể
                if (currentNode.getNodeType() == Node.ELEMENT_NODE) {
                    Element serverEl = (Element) currentNode;
                    
                    // Lấy thuộc tính type từ thẻ cha
                    String serverType = serverEl.getAttribute("type");
                    System.out.println("\n--- Server Loại: " + serverType + " ---");

                    // Lấy tập con chứa các node trực tiếp như host, port
                    NodeList detailList = serverEl.getChildNodes();
                    
                    for (int k = 0; k < detailList.getLength(); k++) {
                        Node detailNode = detailList.item(k);
                        
                        // Chỉ xử lý các node là thẻ (Element), bỏ qua khoảng trắng trắng
                        if (detailNode.getNodeType() == Node.ELEMENT_NODE) {
                            Element childEl = (Element) detailNode;
                            
                            // In ra tên trường và nội dung bên trong
                            System.out.println(childEl.getTagName() + ": " + childEl.getTextContent());
                        }
                    }
                }
            }

        } catch (ParserConfigurationException | SAXException | IOException e) {
            System.err.println("Lỗi xảy ra khi phân tích XML: " + e.getMessage());
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        loadConfiguration("config.xml");
    }
}

Ghi chú quan trọng

Khi duyệt qua danh sách các node con (getChildNodes()), kết quả thường trả về kèm theo các node loại TEXT_NODE tương ứng với dấu xuống dòng hoặc tab trắng trong file XML. Do đó, điều kiện kiểm tra if (nodeType == Node.ELEMENT_NODE) là bắt buộc để đảm bảo dữ liệu trích xuất sạch và logic hoạt động đúng. Việc sử dụng getTextContent() trên thẻ Element cũng tối ưu hơn so với phương pháp truy xuất getFirstChild() truyền thống.

Thẻ: Java XML Parsing DOM API Java IO W3C DOM XML Structured Data

Đăng vào ngày 20 tháng 5 lúc 09:12