Java 應用DOM方式解析XML檔案
阿新 • • 發佈:2019-01-02
引入
java為啥需要解析XML的方法?
xml的優勢:
它可以用來標記資料、定義資料型別,是一種允許使用者對自己的標記語言進行定義的源語言。 它非常適合全球資訊網傳輸,提供統一的方法來描述和交換獨立於應用程式或供應商的結構化資料。是Internet環境中跨平臺的、依賴於內容的技術,也是當今處理分散式結構資訊的有效工具。早在1998年,W3C就釋出了XML1.0規範,使用它來簡化Internet的文件資訊傳輸。
所以啊,java不得不愛。
DOM方式解析XML檔案的步驟
1.從xml獲得生成DOM物件樹的解析器
語句:`
DocumentBuilderFactory docbf = DocumentBuilderFactory.newInstance();`
2.獲得Doucument的生成器,可以利用解析器的newDocumentBuilder()獲得示例
語句:
DocumentBuilder docb = docbf.newDocumentBuilder();
3.用DocumentBuilder的parse()解析xml檔案獲得Doucment物件。
語句:
Document doc = docb.parse("ProfessionalBooks.xml");
4.獲得當前節點的所有子節點
NodeList nodes = doc.getChildNodes();
5.由於xml是是樹狀結構,所以要寫個函式遍歷樹。
public static void ReadTreeStructure(NodeList nodes) {
// 遍歷所有子節點
for (int i = 0; i < nodes.getLength(); i++) {
// 獲得位元組點名,判斷子節點的型別,區分出text型別的node以及element型別的node
if (nodes.item(i).getNodeType() == Node.ELEMENT _NODE) {
System.out.print("該節點的名稱為:" + nodes.item(i).getNodeName() + " ");
String value = ((Text) (nodes.item(i).getFirstChild())).getData().trim();
if (value.getBytes().length != 0) {
System.out.print("該節點的值為:" + value);
}
System.out.println();
System.out.println();
}
// 獲得子節點的值,如果沒有就不輸出
// 如果子節點還有子節點就繼續往下層讀
if (nodes.item(i).getChildNodes().getLength() != 0) {
ReadTreeStructure(nodes.item(i).getChildNodes());
}
}
}
具體程式碼:
1.解析程式碼
package com.imooc.domtest.test;
import java.io.IOException;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.w3c.dom.Document;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.w3c.dom.css.DocumentCSS;
import org.xml.sax.SAXException;
import org.w3c.dom.Text;
import com.sun.org.apache.xalan.internal.xsltc.dom.DocumentCache;
/**
* @author wangahifeng
*
*/
public class MyDOMTest {
/**
* @param args
*/
/*
* 寫一個讀取樹的函式: 1:獲得第一層子節點 2:獲得子節點的屬性 3:完成第一、二步後讀取下一層回掉函式重複執行第一、二步後
*/
public static void ReadTreeStructure(NodeList nodes) {
// 遍歷所有子節點
for (int i = 0; i < nodes.getLength(); i++) {
// 獲得位元組點名,判斷子節點的型別,區分出text型別的node以及element型別的node
if (nodes.item(i).getNodeType() == Node.ELEMENT_NODE) {
System.out.print("該節點的名稱為:" + nodes.item(i).getNodeName() + " ");
String value = ((Text) (nodes.item(i).getFirstChild())).getData().trim();
if (value.getBytes().length != 0) {
System.out.print("該節點的值為:" + value);
}
System.out.println();
System.out.println();
}
// 獲得子節點的值,如果沒有就不輸出
// 如果子節點還有子節點就繼續往下層讀
if (nodes.item(i).getChildNodes().getLength() != 0) {
ReadTreeStructure(nodes.item(i).getChildNodes());
}
}
}
public static void main(String[] args) {
// TODO Auto-generated method stub
// 用DocumentBuilderFactory的newInstance()從xml獲得生成DOM物件樹的解析器
DocumentBuilderFactory docbf = DocumentBuilderFactory.newInstance();
try {
// 顧名思義DocumentBuilder是Doucument的生成器,可以利用解析器的newDocumentBuilder()獲得示例
DocumentBuilder docb = docbf.newDocumentBuilder();
// 用DocumentBuilder的parse()解析xml檔案獲得Doucment物件下面就可以利用它獲得xml檔案的內容了
Document doc = docb.parse("ProfessionalBooks.xml");
System.out.println("該文件有" + doc.getChildNodes().getLength() + "個一層節點");
// 獲得當前節點的所有子節點
NodeList nodes = doc.getChildNodes();
ReadTreeStructure(nodes);
// 下面決定寫個方法一層一層剝開xml檔案,由於xml是樹的結構所以要用到讀取樹的方法
} catch (ParserConfigurationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SAXException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
xml檔案
<?xml version="1.0" encoding="UTF-8"?>
<bookstore id="1" name="書庫">
<booktyple id="1" type="軟體">
<book id="1">
<name>java基礎</name>
<author>王大/author>
<year>2014</year>
<price>89</price>
</book>
<book id="2">
<name>java高階</name>
<year>2004</year>
<price>77</price>
<language>English</language>
</book>
</booktyple>
<booktyple id="2" type="數學">
<book id="1">
<name>高數一</name>
<author>王峰</author>
<year>2014</year>
<price>89</price>
</book>
<book id="2">
<name>高數二</name>
<year>2004</year>
<price>77</price>
<language>English</language>
</book>
</booktyple>
</bookstore>
結果圖
注意:
1.函式裡面,篩選了xml的節點型別,因為xml的節點除了標籤外,還存在text型別的節點,它一般只用來存放文字,沒有NodeName。所以不用獲取。
2.這裡的獲得text型別的value是直接獲得當前的子節點的value,但是element型別的node是沒有value的,只有text型別的node才有,所以油用if語句篩選,至於為啥那樣寫,自己想,想想和用if (value.getBytes().length != null)的區別自己執行下。
3.下圖藍色區域也是一個text型別的節點。放文字的也是text型別的節點,所以算外面element型別的node的子節點。