Java: Java DOM Parser – Đọc, tạo, sửa tài liệu XML

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:

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:

DocumentBuilderFactory 

dbFactory

= DocumentBuilderFactory.newInstance(); DocumentBuilder

dBuilder

=

dbFactory

.newDocumentBuilder();

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

();

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ì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(

"

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ả:

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

{ 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(

"

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

>

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 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

>