根據 DOM,XML 文檔中的每一個成分都是一個節點。java
DOM 是這樣規定的:node
節點類型 | NodeType | Named Constant | nodeName 的返回值 | nodeValue 的返回值 |
Element | 1 | ELEMENT_NODE | element name | null |
Attr | 2 | ATTRIBUTE_NODE | 屬性名稱 | 屬性值 |
Text | 3 | TEXT_NODE | #text | 節點名稱 |
目標:解析xml文件後,Java程序可以獲得xml文件的全部數據程序員
思考:如何在解析以後保留xml的結構信息dom
xml文檔:ui
實例:spa
package Test; /** * 案例:運用DOM解析xml文件,得到xml文件的全部數據 */ import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.NamedNodeMap; import org.w3c.dom.Node; import org.w3c.dom.NodeList; public class DOMDemo { public static void main(String[] args) throws Exception { /** 步驟一:建立一個DocumentBuilderFactory的對象 * 1.定義工廠 API,使應用程序可以從 XML 文檔獲取生成 DOM 對象樹的解析器。 * 2. protected DocumentBuilderFactory() * 用於阻止實例化的受保護構造方法 * 3. static DocumentBuilderFactory newInstance() * 獲取 DocumentBuilderFactory 的新實例。 */ DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); /** 步驟二:建立一個DocumentBuilder的對象 * 1.protected DocumentBuilder() * 受保護的構造方法 * 2.使其從 XML 文檔獲取 DOM 文檔實例。使用此類,應用程序員能夠從 XML 獲取一個 Document。 */ DocumentBuilder db = dbf.newDocumentBuilder(); /** 步驟三:經過DocumentBuilder對象的parse方法加載book.xml文件到當前目錄下 * 1.parse(File f) * 將給定文件的內容解析爲一個 XML 文檔,而且返回一個新的 DOM Document 對象。 */ Document document = db.parse("books.xml"); /** 步驟四:獲取全部book節點的集合 * 1.getElementsByTagName():經過節點的名稱來獲取全部同名節點, * 由於不僅有一個節點,因此就把獲取的全部節點都存放在一個節點集合中。 */ NodeList booklist = document.getElementsByTagName("book"); System.out.println("一共有" + booklist.getLength() + "本書"); /** 步驟五:遍歷每個book節點 * 1.Node item(int index) * 返回集合中的第 index 個項。 * 2.NamedNodeMap getAttributes() * 包含此節點的屬性的 NamedNodeMap(若是它是 Element);不然爲 null。 */ for(int i = 0; i < booklist.getLength(); i++){ // 前提:不知道book節點的id屬性有多少 System.out.println("===========下面開始遍歷第" + (i+1) + "本書的內容==========="); // 經過item方法獲取一個book節點 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方法獲取book節點的某一個屬性 Node attr = attrs.item(j); // 獲取屬性名 System.out.print("屬性名:" + attr.getNodeName()); // 獲取屬性值 System.out.println("--屬性值:" + attr.getNodeValue()); } /* // 前提:已經知道book節點有且只有一個id屬性 // 將book節點進行強制類型轉換,轉換成Element類型 Element ebook = (Element)booklist.item(i); // 經過getAttribute("id")方法來獲取屬性值 String attrValue = ebook.getAttribute("id"); System.out.println("id屬性值爲:" + attrValue); */ /** 步驟六:解析book節點的子節點 * 1.NodeList getChildNodes() * 包含此節點的全部子節點的 NodeList。 */ NodeList childNodes = book.getChildNodes(); // 遍歷childNodes獲取每一個節點的節點名和節點值 System.out.println("第" + (i+1) + "本書共有" + childNodes.getLength() + "個子節點"); for(int k = 0; k < childNodes.getLength(); k++){ /* 若是不對節點類型進行判斷 * 遍歷book節點的子節點後會發現有9個子節點,可是咱們只寫了4個子節點 * 輸出了5個#text節點,這是Text類型的節點。 * 由於空格也屬於子節點,因此也會i被遍歷出來。 * */ // 區分出text類型的node以及element類型的node if(childNodes.item(k).getNodeType() == Node.ELEMENT_NODE){ // 獲取element類型節點的節點名 System.out.print("第" + (k+1) + "個節點的是" + childNodes.item(k).getNodeName() + ": "); /* 當咱們用childNodes.item(k).getNodeValue()這種方法獲取 * element類型的節點的節點值時會返回空,由於他認爲 * <name>冰與火之歌</name>中「冰與火之歌」是<name>的子節點, * 因此返回<name>節點的值固然是null,由於它認爲「冰與火之歌」是節點而不是內容。 * 咱們這時須要返回<name>節點的第一個子節點,再返回第一個子節點的值就能夠了, * 或者用getTextContent()也能夠解決,它會獲取全部子節點的節點值 * */ // System.out.println(childNodes.item(k).getFirstChild().getNodeValue()); System.out.println(childNodes.item(k).getTextContent()); } } } } }
運行結果:code
一共有2本書 ===========下面開始遍歷第1本書的內容=========== 第1本書共有1個屬性 屬性名:id--屬性值:1 第1本書共有9個子節點 第2個節點的是name: 冰與火之歌 第4個節點的是author: 喬治馬丁 第6個節點的是year: 2014 第8個節點的是price: 89 ===========下面開始遍歷第2本書的內容=========== 第2本書共有1個屬性 屬性名:id--屬性值:2 第2本書共有9個子節點 第2個節點的是name: 格林童話 第4個節點的是year: 2004 第6個節點的是price: 66 第8個節點的是language: English