Dom解析XMl文檔

在DOM接口規範中,有四個基本的接口:Document,Node,NodeList以及NamedNodeMap。在這四個基本接口中,Document接口是對文檔進行操作的入口,它是從Node接口繼承過來的。Node接口是其他大多數接口的父類,象Document,Element,Attribute,Text,Comment等接口都是從Node接口繼承過來的。NodeList接口是一個節點的集合,它包含了某個節點中的所有子節點。NamedNodeMap接口也是一個節點的集合,通過該接口,可以建立節點名和節點之間的一一映射關係,從而利用節點名可以直接訪問特定的節點。 

1.Document

Document接口代表了整個XML/HTML文檔,因此,它是整棵文檔樹的根,提供了對文檔中的數據進行訪問和操作的入口。 

2.NodeList

NodeList接口提供了對節點集合的抽象定義,它並不包含如何實現這個節點集的定義。NodeList用於表示有順序關係的一組節點,比如某個節點的子節點序列。另外,它還出現在一些方法的返回值中,例如getElementsByTagName。 

在DOM中,NodeList的對象是"live"的,換句話說,對文檔的改變,會直接反映到相關的NodeList對象中。例如,如果通過DOM獲得一個NodeList對象,該對象中包含了某個Element節點的所有子節點的集合,那麼,當再通過DOM對Element節點進行操作(添加、刪除、改動節點中的子節點)時,這些改變將會自動地反映到NodeList對象中,而不需DOM應用程序再做其他額外的操作。 

NodeList中的每個item都可以通過一個索引來訪問,該索引值從0開始。

3.NamedNodeMap

實現了NamedNodeMap接口的對象中包含了可以通過名字來訪問的一組節點的集合。不過注意,NamedNodeMap並不是從NodeList繼承過來的,它所包含的節點集中的節點是無序的。儘管這些節點也可以通過索引來進行訪問,但這只是提供了枚舉NamedNodeMap中所包含節點的一種簡單方法,並不表明在DOM規範中爲NamedNodeMap中的節點規定了一種排列順序。 

NamedNodeMap表示的是一組節點和其唯一名字的一一對應關係,這個接口主要用在屬性節點的表示上。 與NodeList相同,在DOM中,NamedNodeMap對象也是"live"的。  

4.Dom對象

一切都是節點(對象) 

.Node對象:DOM結構中最爲基本的對象 

•Document對象:代表整個XML的文檔 

•NodeList對象:包含一個或者多個Node的列表 

•Element對象:代表XML文檔中的標籤元素 

5.dom解析xml步驟

<?xml version="1.0" encoding="GB2312"?>    
<students>   
    <student sn="01">   
        <name>張三</name> 
        <age>18</age> 
    </student>       
    <student sn="02">   
        <name>李四</name> 
        <age>20</age>  
    </student> 
</students>
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;

public class dom_xml {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		try{
            DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();//得到DOM解釋器的工廠實例
            DocumentBuilder dbBuilder = dbFactory.newDocumentBuilder();	//從DOM工廠中獲得DOM解析器   
            Document doc = dbBuilder.parse("src/test.xml");//把要解析的xml文檔讀入DOM解析器

            NodeList nodeList = doc.getElementsByTagName("student");
            System.out.println(nodeList.getLength());
            for(int i=0;i<nodeList.getLength();i++){
            	Element node = (Element)nodeList.item(i);
            	System.out.println(node.getElementsByTagName("name").item(0).getFirstChild().getNodeValue());
            	System.out.println(node.getElementsByTagName("age").item(0).getFirstChild().getNodeValue());
            }
		}catch(Exception e){
			e.printStackTrace();
		}
	}
}
張三
18
李四
20

程序詳解:

1)DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();

我們在這裏使用DocumentBuilderFacotry的目的是爲了創建與具體解析器無關的程序,當DocumentBuilderFactory 類的靜態方法newInstance()被調用時,它根據一個系統變量來決定具體使用哪一個解析器。又因爲所有的解析器都服從於JAXP所定義的接口,所 以無論具體使用哪一個解析器,代碼都是一樣的。所以當在不同的解析器之間進行切換時,只需要更改系統變量的值,而不用更改任何代碼。這就是工廠所帶來的好處。 

2)DocumentBuilder dbBuilder = dbFactory.newDocumentBuilder();

當獲得一個工廠對象後,使用它的靜態方法newDocumentBuilder()方法可以獲得一個DocumentBuilder對象,這個對象代表了具體的DOM解析器。但具體是哪一種解析器,微軟的或者IBM的,對於程序而言並不重要。

3) Document doc = dbBuilder.parse("src/test.xml");

DocumentBuilder的parse()方法接受一個XML文檔名作爲輸入參數,返回一個Document對象,這個Document對象就代表了一個XML文檔的樹模型。以後所有的對XML文檔的操作,都與解析器無關,直接在這個Document對象上進行操作就可以了。而具體對Document操作的方法,就是由DOM所定義的了。

4)從上面得到的Document對象開始,我們就可以開始我們的DOM解析了。使用Document對象的getElementsByTagName()方法,我們可以得到一個NodeList對象,一個Node對象代表了一個XML文檔中的一個標籤元素,而NodeList對象,所代表的是一個Node對象的列表 

NodeList nodeList = doc.getElementsByTagName("student");

我們通過這樣一條語句所得到的是XML文檔中所有<student>標籤對應的Node對象的一個列表。然後,我們可以使用NodeList對象的item()方法來得到列表中的每一個Node對象 

Element node = (Element)nodeList.item(i);

5)當一個Node對象被建立之後,保存在XML文檔中的數據就被提取出來並封裝在這個Node中了。在這個例子中,要提取Message標籤內的內容,我們通常會使用Node對象的getNodeValue()方法 

node.getElementsByTagName("name").item(0).getFirstChild().getNodeValue();

注意:請注意,這裏還使用了一個getFirstChild()方法來獲得name下面的第一個子Node對象。雖然在name標籤下面除了文本外並沒有其它子標籤或者屬性,但是我們堅持在這裏使用getFirstChild()方法,這主要和W3C對DOM的定義有關。W3C把標籤內的文本部分也定義成一個Node,所以先要得到代表文本的那個Node,我們才能夠使用getNodeValue()來獲取文本的內容。

向已存在的xml中插入元素:

public static void insertXml(){
		Element students = null;
		Element student = null;
		Element name = null;
		Element age = null;
		try{
			DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
	        DocumentBuilder dbBuilder = dbFactory.newDocumentBuilder();		        
	        Document doc = dbBuilder.parse("src/test.xml");
	        //得到文檔名稱爲school的元素的節點列表
	        NodeList nodeList = doc.getElementsByTagName("students");
	        students = (Element)nodeList.item(0);
	        
	        student = doc.createElement("student");	//創建名稱爲student的元素
	        student.setAttribute("sn", "007");	//設置student的屬性值	        
	        name = doc.createElement("name");	//創建名稱爲name的元素  
            name.appendChild(doc.createTextNode("蝸牛"));	//創建名稱爲 蝸牛 的文本節點並作爲子節點添加到name元素中
            student.appendChild(name);	//將name子元素添加到student中
            age = doc.createElement("age");
            age.appendChild(doc.createTextNode("23"));
            student.appendChild(age);
            students.appendChild(student);	//將student作爲子元素添加到樹的根節點school
            //將內存中的文檔通過文件流生成insertSchool.xml,XmlDocument位於crison.jar下
            ((XmlDocument)doc).write(new FileOutputStream("src/test.xml"));
            System.out.println("成功");
		}catch(Exception e){
			e.printStackTrace();
		}
	}


6.dom基本對象詳解

DOM的基本對象有5個:Document,Node,NodeList,Element和Attr 

Document對象代表了整個XML的文檔,所有其它的Node,都以一定的順序包含在Document對象之內,排列成一個樹形的結構,程序員可以通過遍歷這顆樹來得到XML文檔的所有的內容,這也是對XML文檔操作的起點。我們總是先通過解析XML源文件而得到一個Document對象,然後再來執行後續的操作。此外,Document還包含了創建其它節點的方法,比如createAttribute()用來創建一個Attr對象。它所包含的主要的方法有 

1.createAttribute(String):用給定的屬性名創建一個Attr對象,並可在其後使用setAttributeNode方法來放置在某一個Element對象上面。 

•2createElement(String):用給定的標籤名創建一個Element對象,代表XML文檔中的一個標籤,然後就可以在這個Element對象上添加屬性或進行其它的操作。 

•3createTextNode(String):用給定的字符串創建一個Text對象,Text對象代表了標籤或者屬性中所包含的純文本字符串。如果在一個標籤內沒有其它的標籤,那麼標籤內的文本所代表的Text對象是這個Element對象的唯一子對象。 

4)getElementsByTagName(String):返回一個NodeList對象,它包含了所有給定標籤名字的標籤。 

5)getDocumentElement():返回一個代表這個DOM樹的根元素節點的Element對象,也就是代表XML文檔根元素的那個對象。

7.Node對象所包含的主要的方法有 

•appendChild(org.w3c.dom.Node):爲這個節點添加一個子節點,並放在所有子節點的最後,如果這個子節點已經存在,則先把它刪掉再添加進去。 

•getFirstChild():如果節點存在子節點,則返回第一個子節點,對等的,還有getLastChild()方法返回最後一個子節點。 

•getNextSibling():返回在DOM樹中這個節點的下一個兄弟節點,對等的,還有getPreviousSibling()方法返回其前一個兄弟節點。 

•getNodeName():根據節點的類型返回節點的名稱。 

•getNodeType():返回節點的類型

.getNodeValue():返回節點的值。 

•hasChildNodes():判斷是不是存在有子節點。 

•hasAttributes():判斷這個節點是否存在有屬性。 

•getOwnerDocument():返回節點所處的Document對象。 

•insertBefore(org.w3c.dom.Node new,org.w3c.dom.Node ref):在給定的一個子對象前再插入一個子對象。 

•removeChild(org.w3c.dom.Node):刪除給定的子節點對象 

.replaceChild(org.w3c.dom.Node new,org.w3c.dom.Node old):用一個新的Node對象代替給定的子節點對象。 

•NodeList對象,顧名思義,就是代表了一個包含了一個或者多個Node的列表。可以簡單的把它看成一個Node的數組,我們可以通過方法來獲得列表中的元素: 

•getLength():返回列表的長度。 

•item(int):返回指定位置的Node對象 

Element對象代表的是XML文檔中的標籤元素,繼承於Node,亦是Node的最主要的子對象。在標籤中可以包含有屬性,因而Element對象中有存取其屬性的方法,而任何Node中定義的方法,也可以用在Element對象上面。 

•getElementsByTagName(String):返回一個NodeList對象,它包含了在這個標籤中其下的子孫節點中具有給定標籤名字的標籤。 

•getTagName():返回一個代表這個標籤名字的字符串。 

•getAttribute(String):返回標籤中給定屬性名稱的屬性的值。在這兒需要注意的是,因爲XML文檔中允許有實體屬性出現,而這個方法對這些實體屬性並不適用。這時候需要用到getAttributeNode()方法來得到一個Attr對象來進行進一步的操作 

•getAttributeNode(String):返回一個代表給定屬性名稱的Attr對象。 

9.Attr對象代表了某個標籤中的屬性Attr繼承於Node,但是因爲Attr實際上是包含在Element中的,它並不能被看作是Element的子對象,因而在DOM中Attr並不是DOM樹的一部分,所以Node中的getparentNode(),getpreviousSibling()和getnextSibling()返回的都將是null。也就是說,Attr其實是被看作包含它的Element對象的一部分,它並不作爲DOM樹中單獨的一個節點出現。這一點在使用的時候要同其它的Node子對象相區別



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章