Bài này hướng dẫn bạn sử dụng Java DOM Parser - đọc, tạo, sửa tại liệu XML.
Mô hình đối tượng tài liệu (DOM) là một đề xuất chính thức của World Wide Web Consortium (W3C). Nó định nghĩa một interface cho phép các chương trình truy cập và cập nhật cấu trúc và nội dung của các tài liệu XML.
Nội dung chính
Khi nào nên sử dụng?
Bạn nên sử dụng trình phân tích cú pháp DOM khi:
- Bạn cần phải biết rất nhiều về cấu trúc của một tài liệu XML.
- Bạn cần thao tác với các phần dữ liệu của tài liệu XML (ví dụ: sắp xếp các phần tử nhất định).
- Bạn cần sử dụng thông tin trong một tài liệu XML nhiều lần.
Bạn nhận được những gì?
Khi bạn phân tích cú pháp một tài liệu XML bằng DOM parser, bạn có được cấu trúc cây chứa tất cả các phần tử của tài liệu XML. DOM cung cấp nhiều chức năng mà bạn có thể sử dụng để kiểm tra nội dung và cấu trúc của tài liệu XML.
Ưu điểm
DOM là một giao diện chung để thao tác cấu trúc tài liệu XML. Một trong những mục tiêu thiết kế của nó là giúp Java code được viết cho một trình phân tích cú pháp tuân thủ DOM sẽ chạy trên bất kỳ trình phân tích cú pháp tuân thủ DOM nào khác mà không phải thực hiện bất kỳ sửa đổi nào.
DOM interface
DOM định nghĩa một số interface. Dưới đây là các interface phổ biến nhất:
- Node: Kiểu dữ liệu cơ bản của DOM.
- Element: Phần lớn các đối tượng bạn sẽ xử lý là Elements.
- Attr: Biểu diễn một thuộc tính của một phần tử.
- Text: Nội dung thực tế của Element hoặc Attr.
- Document: Biểu diễn toàn bộ tài liệu XML. Một đối tượng Document thường được gọi là cây DOM.
Các phương thức DOM phổ biến
Khi bạn làm việc với DOM, có một số phương thức bạn sẽ sử dụng thường xuyên:
- Document.getDocumentElement(): Trả về phần tử gốc của tài liệu.
- Node.getFirstChild(): Trả về con đầu tiên của một Node đã cho.
- Node.getLastChild(): Trả về con cuối của một Node đã cho.
- Node.getNextSibling(): Phương thức này trả về sibling (anh em) tiếp theo của một Node đã cho.
- Node.getPreviousSibling(): Phương thức này trả về sibling trước của một Node đã cho.
- Node.getAttribute(attrName): Đối với một Node đã cho, nó trả về thuộc tính với tên được yêu cầu attrName.
Các bước để sử dụng DOM
Sau đây là các bước được sử dụng trong khi phân tích cú pháp một tài liệu bằng cách sử dụng DOM Parser.
- import các gói liên quan đến XML.
- Tạo đối tượng DocumentBuilder.
- Tạo đối tượng Document từ một file hoặc stream.
- Trích xuất phần tử gốc.
- Kiểm tra thuộc tính.
- Kiểm tra các phần tử con.
import các gói liên quan đến XML.
import org.w3c.dom.*; import javax.xml.parsers.*; import java.io.*;
Tạo đối tượng DocumentBuilder.
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance(); DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
Tạo đối tượng Document từ một file hoặc stream.
Tạo đối tượng Document từ một file:
Document doc = dBuilder.parse(inputFile);
Tạo đối tượng Document từ một stream:
StringBuilder xmlStringBuilder = new StringBuilder(); xmlStringBuilder.append("<?xml version="1.0"?> <class> </class>"); ByteArrayInputStream input = new ByteArrayInputStream( xmlStringBuilder.toString().getBytes("UTF-8")); Document doc = builder.parse(input);
Trích xuất phần tử gốc.
Element root = document.getDocumentElement();
Kiểm tra thuộc tính.
//trả về thuộc tính cụ thể getAttribute("attributeName"); //trả về một Map (table) của các cặp name/value getAttributes();
Kiểm tra các phần tử con.
//trả về một list của phần tử con của tên được chỉ định getElementsByTagName("subelementName"); //trả về list tất cả các node con getChildNodes();
Sử dụng Java DOM - Đọc tài liệu XML
Ví dụ: phân tích tập tin XML có nội dung như sau:
<?xml version = "1.0"?> <class> <student id = "1"> <firstname>Vinh</firstname> <lastname>Phan</lastname> <marks>85</marks> </student> <student id = "2"> <firstname>Hoa</firstname> <lastname>Nguyen</lastname> <marks>95</marks> </student> <student id = "3"> <firstname>Phu</firstname> <lastname>Tran</lastname> <marks>90</marks> </student> </class>
Tạo lớp Student.java
package vn.kienthuclaptrinh.javaxml; public class Student { private String id; private String firstName; private String lastName; private String marks; public String getId() { return id; } public void setId(String id) { this.id = id; } public String getFirstName() { return firstName; } public void setFirstName(String firstName) { this.firstName = firstName; } public String getLastName() { return lastName; } public void setLastName(String lastName) { this.lastName = lastName; } public String getMarks() { return marks; } public void setMarks(String marks) { this.marks = marks; } @Override public String toString() { return "@Student, id=" + id + ", firstName=" + firstName + ", lastName=" + lastName + ", marks=" + marks; } }
File DOMExample.java
package vn.kienthuclaptrinh.javaxml; import org.w3c.dom.*; import javax.xml.parsers.*; import java.io.*; import java.util.ArrayList; import java.util.List; public class DOMExample { public static void main(String[] args) { List<Student> listStudents = DOMExample.readListStudents(); // hiển thị các đối tượng student ra màn hình for (Student student : listStudents) { System.out.println(student.toString()); } } public static List<Student> readListStudents() { List<Student> listStudents = new ArrayList<>(); Student student = null; try { // đọc file input.xml File inputFile = new File("D:\\xml\\input.xml"); DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance(); DocumentBuilder dBuilder = dbFactory.newDocumentBuilder(); Document doc = dBuilder.parse(inputFile); doc.getDocumentElement().normalize(); // in phần tử gốc ra màn hình System.out.println("Phần tử gốc:" + doc.getDocumentElement().getNodeName()); // đọc tất cả các phần tử có tên thẻ là "student" NodeList nodeListStudent = doc.getElementsByTagName("student"); // duyệt các phần tử student for (int i = 0; i < nodeListStudent.getLength(); i++) { // tạo đối tượng student student = new Student(); // đọc các thuộc tính của student Node nNode = nodeListStudent.item(i); if (nNode.getNodeType() == Node.ELEMENT_NODE) { Element eElement = (Element) nNode; student.setId(eElement.getAttribute("id")); student.setFirstName(eElement.getElementsByTagName("firstname") .item(0).getTextContent()); student.setLastName(eElement.getElementsByTagName("lastname") .item(0).getTextContent()); student.setMarks(eElement.getElementsByTagName("marks") .item(0).getTextContent()); } // add đối tượng student vào listStudents listStudents.add(student); } } catch (Exception e) { e.printStackTrace(); } return listStudents; } }
Kết quả:
Phần tử gốc:class @Student, id=1, firstName=Vinh, lastName=Phan, marks=85 @Student, id=2, firstName=Hoa, lastName=Nguyen, marks=95 @Student, id=3, firstName=Phu, lastName=Tran, marks=90
Sử dụng Java DOM - Tạo tài liệu XML
Ví dụ sau sẽ tạo ra một tập tin XML có nội dung như sau:
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <class totalStudents="2"> <student rollno="1"> <firstname>Vinh</firstname> <lastname>Phan</lastname> </student> <student rollno="2"> <firstname>Hoa</firstname> <lastname>Nguyen</lastname> </student> </class>
File DOMCreateXMLExample.java
package vn.kienthuclaptrinh.javaxml; import org.w3c.dom.*; import javax.xml.parsers.*; import javax.xml.transform.Transformer; import javax.xml.transform.TransformerFactory; import javax.xml.transform.dom.DOMSource; import javax.xml.transform.stream.StreamResult; import java.io.*; public class DOMCreateXMLExample { public static void main(String argv[]) { try { DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance(); DocumentBuilder dBuilder = dbFactory.newDocumentBuilder(); Document doc = dBuilder.newDocument(); // tạo phần tử gốc có tên class Element rootElement = doc.createElement("class"); // thêm thuộc tính totalStudents vào thẻ class doc.appendChild(rootElement); Attr totalStudentAttr = doc.createAttribute("totalStudents"); totalStudentAttr.setValue("2"); rootElement.setAttributeNode(totalStudentAttr); // tạo phần tử student1 Element student1 = doc.createElement("student"); rootElement.appendChild(student1); // tạo thuộc tính rollno cho student1 Attr attr1 = doc.createAttribute("rollno"); attr1.setValue("1"); student1.setAttributeNode(attr1); // tạo thẻ firstname Element firstname = doc.createElement("firstname"); firstname.appendChild(doc.createTextNode("Vinh")); student1.appendChild(firstname); // tạo thẻ lastname Element lastname = doc.createElement("lastname"); lastname.appendChild(doc.createTextNode("Phan")); student1.appendChild(lastname); // tạo phần tử student2 Element student2 = doc.createElement("student"); rootElement.appendChild(student2); // tạo thuộc tính rollno cho student2 Attr attr2 = doc.createAttribute("rollno"); attr2.setValue("2"); student2.setAttributeNode(attr2); // tạo thẻ firstname Element firstname2 = doc.createElement("firstname"); firstname2.appendChild(doc.createTextNode("Hoa")); student2.appendChild(firstname2); // tạo thẻ lastname Element lastname2 = doc.createElement("lastname"); lastname2.appendChild(doc.createTextNode("Nguyen")); student2.appendChild(lastname2); // ghi nội dung vào file XML TransformerFactory transformerFactory = TransformerFactory.newInstance(); Transformer transformer = transformerFactory.newTransformer(); DOMSource source = new DOMSource(doc); StreamResult result = new StreamResult( new File("D:\\xml\\students.xml")); transformer.transform(source, result); // ghi kết quả ra console để kiểm tra StreamResult consoleResult = new StreamResult(System.out); transformer.transform(source, consoleResult); } catch (Exception e) { e.printStackTrace(); } } }
Kết quả:
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <class totalStudents="2"> <student rollno="1"> <firstname>Vinh</firstname> <lastname>Phan</lastname> </student> <student rollno="2"> <firstname>Hoa</firstname> <lastname>Nguyen</lastname> </student> </class>
Sử dụng Java DOM - Sửa tài liệu XML
Ví dụ: sửa tài liệu XML được tạo ra ở ví dụ trên:
File DOMModifyXMLExample.java
package vn.kienthuclaptrinh.javaxml; import org.w3c.dom.*; import javax.xml.parsers.*; import javax.xml.transform.Transformer; import javax.xml.transform.TransformerFactory; import javax.xml.transform.dom.DOMSource; import javax.xml.transform.stream.StreamResult; import java.io.*; public class DOMModifyXMLExample { public static void main(String argv[]) { try { File inputFile = new File("D:\\xml\\students.xml"); DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance(); DocumentBuilder docBuilder = docFactory.newDocumentBuilder(); Document doc = docBuilder.parse(inputFile); Node classStudent = doc.getFirstChild(); Node student1 = doc.getElementsByTagName("student").item(0); // sửa thuộc tính rollno của student1 NamedNodeMap attr = student1.getAttributes(); Node nodeAttr = attr.getNamedItem("rollno"); nodeAttr.setTextContent("10"); // sửa firstname của student1 NodeList list = student1.getChildNodes(); for (int temp = 0; temp < list.getLength(); temp++) { Node node = list.item(temp); if (node.getNodeType() == Node.ELEMENT_NODE) { Element eElement = (Element) node; if("Vinh".equals(eElement.getTextContent())) { eElement.setTextContent("Test"); } } } // xóa student 2 Node student2 = doc.getElementsByTagName("student").item(1); classStudent.removeChild(student2); // ghi nội dung được sửa ra console TransformerFactory transformerFactory = TransformerFactory.newInstance(); Transformer transformer = transformerFactory.newTransformer(); DOMSource source = new DOMSource(doc); System.out.println("-----------Modified File-----------"); StreamResult consoleResult = new StreamResult(System.out); transformer.transform(source, consoleResult); } catch (Exception e) { e.printStackTrace(); } } }
Kết quả:
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <class totalStudents="2"> <student rollno="10"> <firstname>Test</firstname> <lastname>Phan</lastname> </student> </class>