Java眼中的XML---檔案讀取(一)DOM解析XML檔案
目錄
(一)什麼是XML?
- XML 指可擴充套件標記語言(EXtensible Markup Language)
- XML 是一種標記語言,很類似 HTML
- XML 的設計宗旨是傳輸資料,而非顯示資料
- XML 標籤沒有被預定義。您需要自行定義標籤。
- XML 被設計為具有自我描述性。
- XML 是 W3C 的推薦標準
(二)XML的作用
- 不同應用程式之間通訊、傳輸資訊(訂票程式和支付程式)
- 不同系統間的通訊(例:Windows系統和IOS系統)
- 不同平臺間的資料共享(手機端和PC端)
- 不同APP之間的通訊,不同的平臺間的通訊,不同平臺間的資料共享
(三)DOM解析XML檔案的準備工作
1.建立一個books.xml檔案
<?xml version="1.0" encoding="UTF-8"?> <!-- xml檔案的申明,包括版本號以及編碼字符集 -->
<bookstore> <!-- 根節點 -->
<book id="1"> <!-- 子節點 -->
<name>冰與火之歌</name>
<author>喬治馬丁</author>
<year>2014</year>
<price>88</price>
</book>
<book id="2">
<name>安徒生童話</name>
<year>2004</year>
< price>77</price>
<language>English</language>
</book>
</bookstore>
2.建立一個java專案,並將books.xml檔案拷貝到專案中
3.使用DocumentBuilderFactory物件,DocumentBuilder物件以及Document物件完成對books.xml檔案的載入(一個典型的工廠設計模式),切記Document物件應該匯入org.w3c.dom下的包
// 建立一個DocumentBuilderFactory物件
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
try {
//建立一個DucumentBuilder物件
DocumentBuilder db = dbf.newDocumentBuilder();
//通過DocumentBuilder物件的parse方法載入books.xml檔案到當前專案下
Document document = db.parse("books.xml");
} catch (ParserConfigurationException e) {
e.printStackTrace();
} catch (SAXException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
(四)使用DOM解析XML檔案的屬性名和屬性值
1.獲取所有的book節點的集合,並遍歷每一個book節點
//通過節點名獲取book節點的集合
NodeList bookList = document.getElementsByTagName("book");
System.out.println("一共有" + bookList.getLength() + "本書");
//遍歷每一個book節點
for(int i = 0;i < bookList.getLength(); i++){
//通過迴圈遍歷book節點的集合,並在其中對每個節點進行操作
}
2.獲取book節點中所有屬性的集合,並遍歷每一個book屬性,獲取其屬性名以及屬性值(前提是不知道屬性個數以及屬性名)
//遍歷每一個book節點
for(int i = 0;i < bookList.getLength(); i++){
System.out.println("======下面開始遍歷第" + (i + 1) + "本書的內容======");
//通過item(i)方法獲取每一個book節點,nodeList的索引值從0開始
Node book = bookList.item(i);
//獲取book節點的所有屬性集合
NamedNodeMap attrs = book.getAttributes();
System.out.println("第" + (i + 1) + "本書共有" + attrs.getLength() + "個屬性");
//遍歷book的屬性
for(int j = 0; j < attrs.getLength(); j++){
//通過item(index)方法獲取book節點的某一屬性
Node attr = attrs.item(j);
//獲取屬性名
System.out.print("屬性名:" + attr.getNodeName());
//獲取屬性值
System.out.println("--屬性值:" + attr.getNodeValue());
}
System.out.println("======結束遍歷第" + (i + 1) + "本書的內容======");
}
執行結果
3.已經知道book節點有且只有1個id屬性時,可以將book節點進行強制型別轉換,轉換成element型別
//遍歷每一個book節點
for(int i = 0;i < bookList.getLength(); i++){
System.out.println("======下面開始遍歷第" + (i + 1) + "本書的內容======");
//將book節點強制轉換為element型別
Element book = (Element)bookList.item(i);
//通過getAttribute("id")方法獲取屬性值
String attrValue = book.getAttribute("id");
System.out.println("id屬性的屬性值為:" + attrValue);
System.out.println("======結束遍歷第" + (i + 1) + "本書的內容======");
}
執行結果
(五)使用DOM解析XML檔案的節點名和節點值
1.常用的節點型別
節點型別 | NodeType | nodeName 的返回值 | nodeValue 的返回值 |
---|---|---|---|
Element | 1 | element name | null |
Attr | 2 | 屬性名稱 | 屬性值 |
Text | 3 | #text | 節點內容 |
2.解析book節點的子節點,首先我們先試著獲取book節點下的子節點的數量:
//解析book節點的子節點
NodeList childNodes = book.getChildNodes();
//獲取子節點的數量(即childNodes的長度)
System.out.println("第" + (i +1) + "本書共有" +
childNodes.getLength() + "個子節點");
執行結果:
我們可以看出,結果和我們預料的並不一致,這是為什麼呢?
其實,程式碼並沒有出錯,book節點的子節點的確有9個;
我們可以回看之前節點型別的表格,我們會發現除了我們需要的Element型別的節點外,
book節點下還有5個由空格和換行符組成的Text型別的節點
3.測試輸出book節點下的每個子節點
//測試輸出每個子節點的名稱
for(int k=0;k<childNodes.getLength();k++){
System.out.println(childNodes.item(k).getNodeName());
}
執行結果:
我們可以發現,的確是多出來了5個Text型別的子節點;
所以,我們在獲取book節點的子節點時,需要選擇輸出Element型別的子節點,而不是把所有的子節點全部輸出
4.區分Text型別的節點和Element型別的子節點,並輸出其節點名和節點值
//區分text型別的node以及element型別的node
if(childNodes.item(k).getNodeType() == Node.ELEMENT_NODE){
//獲取了element型別節點的節點名
System.out.print(childNodes.item(k).getNodeName()+ " ");
System.out.println(childNodes.item(k).getNodeValue());
}
執行結果:
可以看出,子節點的節點名是正常輸出了,但是節點值卻都是null
原因就是Element型別節點的節點值都是null
5.獲取Element型別的節點名和節點值
-
System.out.println("--節點值是:" + childNodes.item(k).getFirstChild().getNodeValue());
-
System.out.println("--節點值是:" + childNodes.item(k).getTextContent());
以上兩種方法都能獲取Element型別節點的節點值,而二者的區別在於:
getFirstChild().getNodeValue()方法是先獲取該節點下的第一個子節點,然後輸出其節點值;
getTextContent()方法是獲取該節點下所有的節點值(包括子節點的節點值)