Java与XML联合编程之DOM篇.docx

上传人:b****4 文档编号:5503570 上传时间:2023-05-08 格式:DOCX 页数:12 大小:34.80KB
下载 相关 举报
Java与XML联合编程之DOM篇.docx_第1页
第1页 / 共12页
Java与XML联合编程之DOM篇.docx_第2页
第2页 / 共12页
Java与XML联合编程之DOM篇.docx_第3页
第3页 / 共12页
Java与XML联合编程之DOM篇.docx_第4页
第4页 / 共12页
Java与XML联合编程之DOM篇.docx_第5页
第5页 / 共12页
Java与XML联合编程之DOM篇.docx_第6页
第6页 / 共12页
Java与XML联合编程之DOM篇.docx_第7页
第7页 / 共12页
Java与XML联合编程之DOM篇.docx_第8页
第8页 / 共12页
Java与XML联合编程之DOM篇.docx_第9页
第9页 / 共12页
Java与XML联合编程之DOM篇.docx_第10页
第10页 / 共12页
Java与XML联合编程之DOM篇.docx_第11页
第11页 / 共12页
Java与XML联合编程之DOM篇.docx_第12页
第12页 / 共12页
亲,该文档总共12页,全部预览完了,如果喜欢就下载吧!
下载资源
资源描述

Java与XML联合编程之DOM篇.docx

《Java与XML联合编程之DOM篇.docx》由会员分享,可在线阅读,更多相关《Java与XML联合编程之DOM篇.docx(12页珍藏版)》请在冰点文库上搜索。

Java与XML联合编程之DOM篇.docx

Java与XML联合编程之DOM篇

Java與XML聯合編程之DOM篇

來源︰網絡轉載作者︰揚帆時間︰2005-08-24點擊︰991

DOM初步 

DOM是Document Object Model的縮寫,即文檔對象模型。

前面說過,XML將數據組織為一顆樹,所以DOM就是對這顆樹的一個對象描敘。

通俗的說,就是通過解析XML文檔,為XML文檔在邏輯上建立一個樹模型,樹的節點是一個個對象。

我們通過存取這些對象就能夠存取XML文檔的內容。

 

下面我們來看一個簡單的例子,看看在DOM中,我們是如何來操作一個XML文檔的。

 

這是一個XML文檔,也是我們要操作的對象︰ 

xml version="1.0" encoding="UTF-8"?

>

Good-bye serialization, hello Java!

 

下面,我們需要把這個文檔的內容解析到一個個的Java對象中去供程序使用,利用JAXP,我們只需幾行代碼就能做到這一點。

首先,我們需要建立一個解析器工廠,以利用這個工廠來獲得一個具體的解析器對象︰ 

DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); 

我們在這里使用DocumentBuilderFacotry的目的是為了創建與具體解析器無關的程序,當DocumentBuilderFactory類的靜態方法newInstance()被調用時,它根據一個系統變量來決定具體使用哪一個解析器。

又因為所有的解析器都服從于JAXP所定義的接口,所以無論具體使用哪一個解析器,代碼都是一樣的。

所以當在不同的解析器之間進行切換時,只需要更改系統變量的值,而不用更改任何代碼。

這就是工廠所帶來的好處。

這個工廠模式的具體實現,可以參看下面的類圖。

 

DocumentBuilder db = dbf.newDocumentBuilder(); 

當獲得一個工廠對象後,使用它的靜態方法newDocumentBuilder()方法可以獲得一個DocumentBuilder對象,這個對象代表了具體的DOM解析器。

但具體是哪一種解析器,微軟的或者IBM的,對于程序而言並不重要。

 

然後,我們就可以利用這個解析器來對XML文檔進行解析了︰ 

Document doc = db.parse("c:

/xml/message.xml"); 

DocumentBuilder的parse()方法接受一個XML文檔名覂^ 淙氬問 禱匾桓ocument對象,這個Document對象就代表了一個XML文檔的樹模型。

以後所有的對XML文檔的操作,都與解析器無關,直接在這個Document對象上進行操作就可以了。

而具體對Document操作的方法,就是由DOM所定義的了。

 

Jaxp支持W3C所推薦的DOM 2。

如果你對DOM很熟悉,那麼下面的內容就很簡單了︰只需要按照DOM的規範來進行方法調用就可以。

當然,如果你對DOM不清楚,也不用著急,後面我們會有詳細的介紹。

在這兒,你所要知道並牢記的是︰DOM是用來描敘XML文檔中的數據的模型,引入DOM的全部原因就是為了用這個模型來操作XML文檔的中的數據。

DOM規範中定義有節點(即對象)、屬性和方法,我們通過這些節點的存取來存取XML的數據。

 

從上面得到的Document對象開始,我們就可以開始我們的DOM之旅了。

使用Document對象的getElementsByTagName()方法,我們可以得到一個NodeList對象,一個Node對象代表了一個XML文檔中的一個標簽元素,而NodeList對象,觀其名而知其意ㄐ@淼氖且桓ode對象的列表︰ 

NodeList nl = doc.getElementsByTagName("message"); 

我們通過這樣一條語句所得到的是XML文檔中所有標簽對應的Node對象的一個列表。

然後,我們可以使用NodeList對象的item()方法來得到列表中的每一個Node對象︰ 

Node my_node = nl.item(0); 

當一個Node對象被建立之後,保存在XML文檔中的數據就被提取出來並封裝在這個Node中了。

在這個例子中,要提取Message標簽內的內容,我們通常會使用Node對象的getNodeValue()方法︰ 

String message = my_node.getFirstChild().getNodeValue(); 

請注意,這里還使用了一個getFirstChild()方法來獲得message下面的第一個子Node對象。

雖然在message標簽下面除了文本外並沒有其它子標簽或者屬性,但是我們堅持在這里使用getFirseChild()方法,這主要和W3C對DOM的定義有關。

W3C把標簽內的文本部分也定義成一個Node,所以先要得到代表文本的那個Node,我們才能夠使用getNodeValue()來獲取文本的內容。

 

現在,既然我們已經能夠從XML文件中提取出數據了,我們就可以把這些數據用在合適的地方,來構築應用程序。

 

下面的內容,我們將更多的關注DOM,為DOM作一個較為詳細的解析,使我們使用起來更為得心應手。

 

DOM詳解 

1.基本的DOM對象 

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

下面就這些對象的功能和實現的方法作一個大致的介紹。

 

Document對象代表了整個XML的文檔,所有其它的Node,都以一定的順序包含在Document對象之內,排列成一個樹形的結構,程序員可以通過遍歷這顆樹來得到XML文檔的所有的內容,這也是對XML文檔操作的起點。

我們總是先通過解析XML啈葆玫揭桓ocument對象,然後再來執行後續的操作。

此外,Document還包含了創建其它節點的方法,比如createAttribut()用來創建一個Attr對象。

它所包含的主要的方法有︰ 

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

 

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

 

createTextNode(String)︰用給定的字符串創建一個Text對象,Text對象代表了標簽或者屬性中所包含的純文本字符串。

如果在一個標簽內沒有其它的標簽,那麼標簽內的文本所代表的Text對象是這個Element對象的唯一子對象。

 

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

 

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

 

Node對象是DOM結構中最為基本的對象,代表了文檔樹中的一個抽象的節點。

在實際使用的時候,很少會真正的用到Node這個對象,而是用到諸如Element、Attr、Text等Node對象的子對象來操作文檔。

Node對象為這些對象提供了一個抽象的、公共的根。

雖然在Node對象中定義了對其子節點進行存取的方法,但是有一些Node子對象,比如Text對象,它並不存在子節點,這一點是要注意的。

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文檔中允許有實體屬性出現,而這個方法對這些實體屬性並不適用。

這時候需要用到getAttributeNodes()方法來得到一個Attr對象來進行進一步的操作。

 

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

 

Attr對象代表了某個標簽中的屬性。

Attr繼承于Node,但是因為Attr實際上是包含在Element中的,它並不能被看作是Element的子對象,因而在DOM中Attr並不是DOM樹的一部分,所以Node中的getparentNode(),getpreviousSibling()和getnextSibling()返回的都將是null。

也就是說,Attr其實是被看作包含它的Element對象的一部分,它並不作為DOM樹中單獨的一個節點出現。

這一點在使用的時候要同其它的Node子對象相區別。

 

需要說明的是,上面所說的DOM對象在DOM中都是用接口定義的,在定義的時候使用的是與具體語言無關的IDL語言來閎?

W摹R蚨OM其實可以在任何面向對象的語言中實現,只要它實現了DOM所定義的接口和功能就可以了。

同時,有些方法在DOM中並沒有定義,是用IDL的屬性來表達的,當被映射到具體的語言時,這些屬性被映射為相應的方法。

 

2.DOM實例 

有了上面的介紹,相信你對DOM理解的更多了吧。

下面的例子將讓你對DOM更加熟悉起來。

 

先說說這個例子到底要做的是什麼吧,我們希望在一個名為link.xml文件中保存了一些URL地址,通過一個簡單的程序,我們可以通過DOM把這些URL讀出並顯示出來,也可以反過來向這個XML文件中寫入加入的URL地址。

很簡單,卻很實用,也足夠來例示DOM的絕大部分用法了。

 

XML文件本身不復雜,就不給出它的DTD了。

link.xml:

 

xml version="1.0" standalone="yes"?

>

JSP Insider

JSP Insider

2

1

2001

A JSP information site.

The makers of Java

Sun Microsystems

3

1

2001

Sun Microsystem's website.

The standard JSP container

http:

//jakarta.apache.org

Apache Group

4

1

2001

Some great software.

 

第一個程序我們稱為xmldisplay.java,具體的程序清單可以在附件中找到。

主要的功能就是讀取這個XML文件中各個節點的內容,然後在格式化輸出在System.out上,我們來看看這個程序︰ 

import javax.xml.parsers.*;

import org.w3c.dom.*; 

這是引入必要的類,因為在這里使用的是Sun所提供的XML解析器,因而需要引入java.xml.parsers包,其中包含了有DOM解析器和SAX解析器的具體實現。

org.w3c.dom包中定義了w3c所制定的DOM接口。

 

DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();

DocumentBuilder builder=factory.newDocumentBuilder();

Document doc=builder.parse("links.xml");

doc.normalize(); 

除了上面講到的,還有一個小技巧,對Document對象調用normalize(),可以去掉XML文檔中作為格式化內容的空白而映射在DOM樹中的不必要的Text Node對象。

否則你得到的DOM樹可能並不如你所想象的那樣。

特別是在輸出的時候,這個normalize()更為有用。

 

NodeList links =doc.getElementsByTagName("link"); 

剛才說過,XML文檔中的空白符也會被作為對象映射在DOM樹中。

因而,直接調用Node方法的getChildNodes方法有時候會有些問題,有時不能夠返回所期望的NodeList對象。

解決的辦法是使用Element的getElementByTagName(String),返回的NodeLise就是所期待的對象了。

然後,可以用item()方法提取想要的元素。

 

for (int i=0;i

Element link=(Element) links.item(i);

System.out.print("Content:

 ");

System.out.println(link.getElementsByTagName("text").item(0).getFirstChild().getNodeValue());

System.out.print("URL:

 ");

System.out.println(link.getElementsByTagName("url").item(0).getFirstChild().getNodeValue());

System.out.print("Author:

 ");

System.out.println(link.getElementsByTagName("author").item(0).getFirstChild().getNodeValue());

System.out.print("Date:

 ");

Element linkdate=(Element) link.getElementsByTagName("date").item(0);

String day=linkdate.getElementsByTagName("day").item(0).getFirstChild().getNodeValue();

String month=linkdate.getElementsByTagName("month").item(0).getFirstChild().getNodeValue();

String year=linkdate.getElementsByTagName("year").item(0).getFirstChild().getNodeValue();

System.out.println(day+"-"+month+"-"+year);

System.out.print("Description:

 ");

System.out.println(link.getElementsByTagName("description").item(0).getFirstChild().getNodeValue());

System.out.println();

上面的代碼片斷就完成了對XML文檔內容的格式化輸出。

只要注意到一些細節的問題,比如getFirstChile()方法和getElementsByTagName()方法的使用,這些還是比較容易的。

 

下面的內容,就是在修改了DOM樹後重新寫入到XML文檔中去的問題了。

這個程序名為xmlwrite.java。

在JAXP1.0版本中,並沒有直接的類和方法能夠處理XML文檔的寫入問題,需要借助其它包中的一些輔助類。

而在JAXP1.1版本中,引入了對XSLT的支持,所謂XSLT,就是對XML文檔進行變換(Translation)後,得到一個新的文檔結構。

利用這個新加入的功能,我們就能夠很方便的把新生成或者修改後的DOM樹從新寫回到XML文件中去了,下面我們來看看代碼的實現,這段代碼翔x饕 δ蓯竅inks.xml文件中加入一個新的link節點︰ 

import javax.xml.parsers.*;

import javax.xml.transform.*;

import javax.xml.transform.dom.DOMSource;

import javax.xml.transform.stream.StreamResult;

import org.w3c.dom.*; 

新引入的java.xml.transform包中的幾個類,就是用來處理XSLT變換的。

 

我們希望在上面的XML文件中加入一個新的link節點,因而首先還是要讀入links.xml文件,構建一個DOM樹,然後再對這個DOM樹進行修改(添加節點),最後把修改後的DOM寫回到links.xml文件中︰ 

DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();

DocumentBuilder builder=factory.newDocumentBuilder();

Document doc=builder.parse("links.xml");

doc.normalize();

//---取得變量----

String text="Hanzhong's Homepage";

String url="";

String author="Hzliu Liu";

String discription="A site from Hanzhong Liu, give u lots of suprise!

!

!

"; 

為了看清重點,簡化程序,我們把要加入的內容硬編碼到記憶String對象中,而實際操作中,往往利用一個界面來提取用戶輸入,或者通過JDBC從數據庫中提取想要的內容。

 

Text textseg;

Element link=doc.createElement("link"); 

首先應該明了的是,無論什麼類型的Node,Text型的也好,Attr型的也好,Element型的也好,它們的創建都是通過Document對象中的createXXX()方法來創建的(XXX代表具體要創建的類型),因此,我們要向XML文檔中添加一個link項目,首先要創建一個link對象︰ 

Element linktext=doc.createElement("text");

textseg=doc.createTextNode(text);

linktext.appendChild(textseg);

link.appendChild(linktext);

Element linkurl=doc.createElement("url");

textseg=doc.createTextNode(url);

linkurl.appendChild(textseg);

link.appendChild(linkurl);

Element linkauthor=doc.createElement("author");

textseg=doc.createTextNode(author);

linkauthor.appendChild(textseg);

link.appendChild(linkauthor);

java.util.Calendar rightNow = java.util.Calendar.getInstance();

String day=Integer.toString(rightNow.get(java.util.Calendar.DAY_OF_MONTH));

String month=Integer.toString(rightNow.get(java.util.Calendar.MONTH));

String year=Integer.toString(rightNow.get(java.util.Calendar.YEAR));

Element linkdate=doc.createElement("dat

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 小学教育 > 语文

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2