Bài viết này sẽ 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.
Mục lục bài viết:
Tóm Tắt
1. 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.
2. Ư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.
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.
3. 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.
4. 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.
5. 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:
DocumentBuilderFactorydbFactory
= DocumentBuilderFactory.newInstance(); DocumentBuilderdBuilder
=dbFactory
.newDocumentBuilder();
Tạo đối tượng Document từ một file:
Documentdoc
= 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:
Elementroot
= 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/valuegetAttributes
();
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ỉ địnhgetElementsByTagName
("subelementName"
); //trả về list tất cả các node congetChildNodes
();
6. Sử dụng Java DOM – Đọc tài liệu XML
Ví dụ: phân tích tập tin XML input.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
v1study.com.javadomparserxml;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
v1study.com.javadomparserxml;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ìnhfor
(Studentstudent
:listStudents
) {System
.out.println(student
.toString()); } }public static
List<Student>readListStudents
() { List<Student>listStudents
=new
ArrayList<>(); Student student =null
;try
{ // đọc file input.xml FileinputFile
=new
File("
input.xml"
); DocumentBuilderFactorydbFactory
= DocumentBuilderFactory.newInstance(); DocumentBuilderdBuilder
=dbFactory
.newDocumentBuilder(); Documentdoc
=dBuilder
.parse(inputFile
);doc
.getDocumentElement().normalize(); // in phần tử gốc ra màn hìnhSystem
.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" NodeListnodeListStudent
=doc
.getElementsByTagName("student"
); // duyệt các phần tử studentfor
(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 NodenNode
=nodeListStudent
.item(i);if
(nNode
.getNodeType() == Node.ELEMENT_NODE) { ElementeElement
= (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 listStudentslistStudents
.add(student); } }catch
(Exception
e) { e.printStackTrace(); }return
listStudents
; } }
Kết quả:
Root element: 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
7. 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ó tên students.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
v1study.com.javadomparserxml;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
{ DocumentBuilderFactorydbFactory
= DocumentBuilderFactory.newInstance(); DocumentBuilderdBuilder
=dbFactory
.newDocumentBuilder(); Documentdoc
=dBuilder
.newDocument(); // tạo phần tử gốc có tên class ElementrootElement
=doc
.createElement("class"
); // thêm thuộc tính totalStudents vào thẻ classdoc
.appendChild(rootElement
); AttrtotalStudentAttr
=doc
.createAttribute("totalStudents"
);totalStudentAttr
.setValue("2"
);rootElement
.setAttributeNode(totalStudentAttr
); // tạo phần tử student1 Elementstudent1
=doc
.createElement("student"
);rootElement
.appendChild(student1
); // tạo thuộc tính rollno cho student1 Attrattr1
=doc
.createAttribute("rollno"
);attr1
.setValue("1"
);student1
.setAttributeNode(attr1
); // tạo thẻ firstname Elementfirstname
=doc
.createElement("firstname"
);firstname
.appendChild(doc
.createTextNode("Vinh"
));student1
.appendChild(firstname
); // tạo thẻ lastname Elementlastname
=doc
.createElement("lastname"
);lastname
.appendChild(doc
.createTextNode("Phan"
));student1
.appendChild(lastname
); // tạo phần tử student2 Elementstudent2
=doc
.createElement("student"
);rootElement
.appendChild(student2
); // tạo thuộc tính rollno cho student2 Attrattr2
=doc
.createAttribute("rollno"
);attr2
.setValue("2"
);student2
.setAttributeNode(attr2
); // tạo thẻ firstname Elementfirstname2
=doc
.createElement("firstname"
);firstname2
.appendChild(doc
.createTextNode("Hoa"
));student2
.appendChild(firstname2
); // tạo thẻ lastname Elementlastname2
=doc
.createElement("lastname"
);lastname2
.appendChild(doc
.createTextNode("Nguyen"
));student2
.appendChild(lastname2
); // ghi nội dung vào file XML TransformerFactorytransformerFactory
= TransformerFactory.newInstance(); Transformertransformer
=transformerFactory
.newTransformer(); DOMSourcesource
=new
DOMSource(doc
); StreamResultresult
=new
StreamResult(new
File("
students.xml"
));transformer
.transform(source
,result
); // ghi kết quả ra console để kiểm tra StreamResultconsoleResult
=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
>
8. Sử dụng Java DOM – Sửa tài liệu XML
Ví dụ: sửa tài liệu XML students.xml được tạo ra ở ví dụ trên:
File DOMModifyXMLExample.java:
package
v1study.com.javadomparserxml
;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("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 student1NamedNodeMap attr
=student1
.getAttributes();Node nodeAttr
=attr
.getNamedItem("rollno"
);nodeAttr
.setTextContent("10"
); // sửa firstname của student1NodeList 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 2Node student2
=doc
.getElementsByTagName("student"
).item(1
);classStudent
.removeChild(student2
); // ghi nội dung được sửa ra consoleTransformerFactory 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
>