Cách Đọc File XML Java ( DOM Parser )

Mục lục

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.

Lưu ý: Trình phân tích cú pháp DOM chậm và tiêu tốn nhiều bộ nhớ khi nó đọc một tài liệu XML lớn vì nó tải tất cả các nút vào bộ nhớ để duyệt và thao tác. Thay vào đó, chúng ta nên xem xét trình phân tích cú pháp SAX để đọc một tài liệu XML có kích thước lớn, SAX nhanh hơn DOM và sử dụng ít bộ nhớ hơn.

Document Object Model (DOM) là gì?

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.

  • Là <company>phần tử gốc.
  • Với <staff>, <firstname> and all <?>là các nút phần tử.
  • Nút văn bản là giá trị được bao bọc bởi các nút phần tử; ví dụ, <firstname>tuan</firstname>là tuannút văn bản.
  • Thuộc tính là một phần của nút phần tử; ví dụ, <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)

Đọc hoặc phân tích cú pháp tệp XML

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]

Phân tích và đọc file XML Java ( Unicode )

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]

Phân tích cú pháp phản hồi XML API của Alexa

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!

Từ khóa » đọc File Xml Trong Java