Mạng xã hội
Hoặc copy link
Hướng dẫn này sẽ chỉ cho bạn cách sử dụng DOM parser tích hợp sẵn của Java để đọc file XML.
DOM là viết tắt của Document Object Model ( gọi nôm na là mô hình tài liệu đối tượng ) sử dụng các nút để biểu diễn tài liệu HTML hoặc XML dưới dạng cấu trúc cây.
Ví dụ dưới đây là một tài liệu XML đơn giản:
<company>
<staff id="1001">
<firstname>tuan</firstname>
<lastname>nguyen</lastname>
<nickname>nguyentuan</nickname>
<salary currency="USD">10000</salary>
</staff>
</company>
Các thuật ngữ chung của DOM.
<company>
phần tử gốc.<staff>, <firstname> and all <?>
là các nút phần tử.<firstname>tuan</firstname>
là tuan
nút văn bản.<staff id="1001">
là id
thuộc tính của staff
phần tử.Xem thêm nếu bạn vẫn chưa hiểu: Wikipedia – Mô hình đối tượng tài liệu (DOM) hoặc Mozilla – Mô hình đối tượng tài liệu (DOM)
Ví dụ này cho bạn thấy cách sử dụng các API trình phân tích cú pháp DOM tích hợp sẵn của Java để đọc hoặc phân tích cú pháp tệp XML.
2.1 Xem lại tệp XML bên dưới.
<?xml version="1.0"?>
<company>
<staff id="1001">
<firstname>tuan</firstname>
<lastname>nguyen</lastname>
<nickname>nguyentuan</nickname>
<salary currency="USD">100000</salary>
</staff>
<staff id="2001">
<firstname>low</firstname>
<lastname>yin fong</lastname>
<nickname>fong fong</nickname>
<salary currency="INR">200000</salary>
</staff>
</company>
2.2 Dưới đây là ví dụ về DOM parser về việc phân tích cú pháp hoặc đọc tệp XML ở trên.
package com.sharecs.xml.dom;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
public class ReadXmlDomParser {
private static final String FILENAME = "/users/sharecs/staff.xml";
public static void main(String[] args) {
// Instantiate the Factory
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
try {
// optional, but recommended
// process XML securely, avoid attacks like XML External Entities (XXE)
dbf.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
// parse XML file
DocumentBuilder db = dbf.newDocumentBuilder();
Document doc = db.parse(new File(FILENAME));
// optional, but recommended
// http://stackoverflow.com/questions/13786607/normalization-in-dom-parsing-with-java-how-does-it-work
doc.getDocumentElement().normalize();
System.out.println("Root Element :" + doc.getDocumentElement().getNodeName());
System.out.println("------");
// get <staff>
NodeList list = doc.getElementsByTagName("staff");
for (int temp = 0; temp < list.getLength(); temp++) {
Node node = list.item(temp);
if (node.getNodeType() == Node.ELEMENT_NODE) {
Element element = (Element) node;
// get staff's attribute
String id = element.getAttribute("id");
// get text
String firstname = element.getElementsByTagName("firstname").item(0).getTextContent();
String lastname = element.getElementsByTagName("lastname").item(0).getTextContent();
String nickname = element.getElementsByTagName("nickname").item(0).getTextContent();
NodeList salaryNodeList = element.getElementsByTagName("salary");
String salary = salaryNodeList.item(0).getTextContent();
// get salary's attribute
String currency = salaryNodeList.item(0).getAttributes().getNamedItem("currency").getTextContent();
System.out.println("Current Element :" + node.getNodeName());
System.out.println("Staff Id : " + id);
System.out.println("First Name : " + firstname);
System.out.println("Last Name : " + lastname);
System.out.println("Nick Name : " + nickname);
System.out.printf("Salary [Currency] : %,.2f [%s]%n%n", Float.parseFloat(salary), currency);
}
}
} catch (ParserConfigurationException | SAXException | IOException e) {
e.printStackTrace();
}
}
}
Kết quả đưa ra cho bạn thấy:
Root Element :company
------
Current Element :staff
Staff Id : 1001
First Name : tuan
Last Name : nguyen
Nick Name : nguyentuan
Salary [Currency] : 100,000.00 [USD]
Current Element :staff
Staff Id : 2001
First Name : low
Last Name : yin fong
Nick Name : fong fong
Salary [Currency] : 200,000.00 [INR]
Trong phân tích DOM, không có sự khác biệt giữa việc đọc tệp XML bình thường và Unicode.
Ví dụ tệp XML bên dưới có chứa một số ký tự Trung Quốc (Unicode).
<?xml version="1.0"?>
<company>
<staff id="1001">
<firstname>揚</firstname>
<lastname>木金</lastname>
<nickname>sharecs</nickname>
<salary currency="USD">100000</salary>
</staff>
<staff id="2001">
<firstname>low</firstname>
<lastname>yin fong</lastname>
<nickname>fong fong</nickname>
<salary currency="INR">200000</salary>
</staff>
</company>
Ví dụ dưới đây phân tích cú pháp tệp XML ở trên; nó lặp lại tất cả các nút lần lượt và in ra.
package com.sharecs.xml.dom;
import org.w3c.dom.*;
import org.xml.sax.SAXException;
import javax.xml.XMLConstants;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import java.io.IOException;
import java.io.InputStream;
public class ReadXmlDomParserLoop {
public static void main(String[] args) {
// Instantiate the Factory
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
try (InputStream is = readXmlFileIntoInputStream("staff-unicode.xml")) {
// parse XML file
DocumentBuilder db = dbf.newDocumentBuilder();
// read from a project's resources folder
Document doc = db.parse(is);
System.out.println("Root Element :" + doc.getDocumentElement().getNodeName());
System.out.println("------");
if (doc.hasChildNodes()) {
printNote(doc.getChildNodes());
}
} catch (ParserConfigurationException | SAXException | IOException e) {
e.printStackTrace();
}
}
private static void printNote(NodeList nodeList) {
for (int count = 0; count < nodeList.getLength(); count++) {
Node tempNode = nodeList.item(count);
// make sure it's element node.
if (tempNode.getNodeType() == Node.ELEMENT_NODE) {
// get node name and value
System.out.println("\nNode Name =" + tempNode.getNodeName() + " [OPEN]");
System.out.println("Node Value =" + tempNode.getTextContent());
if (tempNode.hasAttributes()) {
// get attributes names and values
NamedNodeMap nodeMap = tempNode.getAttributes();
for (int i = 0; i < nodeMap.getLength(); i++) {
Node node = nodeMap.item(i);
System.out.println("attr name : " + node.getNodeName());
System.out.println("attr value : " + node.getNodeValue());
}
}
if (tempNode.hasChildNodes()) {
// loop again if has child nodes
printNote(tempNode.getChildNodes());
}
System.out.println("Node Name =" + tempNode.getNodeName() + " [CLOSE]");
}
}
}
// read file from project resource's folder.
private static InputStream readXmlFileIntoInputStream(final String fileName) {
return ReadXmlDomParserLoop.class.getClassLoader().getResourceAsStream(fileName);
}
}
Kết quả:
Root Element :company
------
Node Name =company [OPEN]
Node Value =
揚
木金
sharecs
100000
low
yin fong
fong fong
200000
Node Name =staff [OPEN]
Node Value =
揚
木金
sharecs
100000
attr name : id
attr value : 1001
Node Name =firstname [OPEN]
Node Value =揚
Node Name =firstname [CLOSE]
Node Name =lastname [OPEN]
Node Value =木金
Node Name =lastname [CLOSE]
Node Name =nickname [OPEN]
Node Value =sharecs
Node Name =nickname [CLOSE]
Node Name =salary [OPEN]
Node Value =100000
attr name : currency
attr value : USD
Node Name =salary [CLOSE]
Node Name =staff [CLOSE]
Node Name =staff [OPEN]
Node Value =
low
yin fong
fong fong
200000
attr name : id
attr value : 2001
Node Name =firstname [OPEN]
Node Value =low
Node Name =firstname [CLOSE]
Node Name =lastname [OPEN]
Node Value =yin fong
Node Name =lastname [CLOSE]
Node Name =nickname [OPEN]
Node Value =fong fong
Node Name =nickname [CLOSE]
Node Name =salary [OPEN]
Node Value =200000
attr name : currency
attr value : INR
Node Name =salary [CLOSE]
Node Name =staff [CLOSE]
Node Name =company [CLOSE]
Ví dụ này cho thấy cách sử dụng trình phân tích cú pháp DOM để phân tích cú pháp phản hồi XML từ API của Alexa.
Gửi yêu cầu tới API Alexa sau.
https://data.alexa.com/data?cli=10&url=sharecs.net
API Alexa sẽ trả về phản hồi XML sau. Xếp hạng Alexa nằm bên trong POPULARITY phần tử, TEXT thuộc tính.
<!-- Need more Alexa data? Find our APIs here: https://aws.amazon.com/alexa/ -->
<ALEXA VER="0.9" URL="sharecs.net/" HOME="0" AID="=" IDN="sharecs.net/">
<SD>
<POPULARITY URL="sharecs.net/" TEXT="1252153" SOURCE="panel"/>
<REACH RANK="1121536"/>
<RANK DELTA="+379865"/>
<COUNTRY CODE="VN" NAME="Vietnam" RANK="17410"/>
</SD>
</ALEXA>
Mình sẽ phân tích cú pháp DOM để chọn trực tiếp POPULARITY phần tử và in ra giá trị của TEXT thuộc tính.
package com.sharecs.xml.dom;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import javax.xml.XMLConstants;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import java.io.InputStream;
import java.net.URL;
import java.net.URLConnection;
public class ReadXmlAlexaApi {
private static final String ALEXA_API = "http://data.alexa.com/data?cli=10&url=";
private final DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
public static void main(String[] args) {
ReadXmlAlexaApi obj = new ReadXmlAlexaApi();
int alexaRanking = obj.getAlexaRanking("sharecs.net");
System.out.println("Ranking: " + alexaRanking);
}
public int getAlexaRanking(String domain) {
int result = 0;
String url = ALEXA_API + domain;
try {
URLConnection conn = new URL(url).openConnection();
try (InputStream is = conn.getInputStream()) {
// unknown XML better turn on this
dbf.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
DocumentBuilder dBuilder = dbf.newDocumentBuilder();
Document doc = dBuilder.parse(is);
Element element = doc.getDocumentElement();
// find this tag "POPULARITY"
NodeList nodeList = element.getElementsByTagName("POPULARITY");
if (nodeList.getLength() > 0) {
Element elementAttribute = (Element) nodeList.item(0);
String ranking = elementAttribute.getAttribute("TEXT");
if (!"".equals(ranking)) {
result = Integer.parseInt(ranking);
}
}
}
} catch (Exception e) {
e.printStackTrace();
throw new IllegalArgumentException("Invalid request for domain : " + domain);
}
return result;
}
}
Kết quả trả về miền sharecs.net Ranking: 17410
Cảm ơn các bạn đã ghé thăm. Chúc các bạn thành công!