構(gòu)建自己的輕量級XML DOM分析程序
發(fā)布時間:2008-03-22 閱讀數(shù): 次 來源:網(wǎng)樂原科技
XML正迅快速的成為數(shù)據(jù)存儲和交換的標(biāo)準(zhǔn)格式流行開來了?,F(xiàn)在可用的完整的Java XML分析器非常龐大而且功能強大--但是實現(xiàn)這些強大的功能的同時也要消耗等量的資源。舉例來說,流行的Apache Xerces-J分析器超過1.7 MB,而最新的完整的Sun JAXP(用于XML處理的Java應(yīng)用編程接口)實現(xiàn)程序包超過了3MB。因此使用一個功能強大的XML分析器可能過于浪費。如果配置環(huán)境是一個Java小程序或者是一個J2ME應(yīng)用程序,網(wǎng)絡(luò)帶寬或者系統(tǒng)存儲器的制約可能根本不能夠使用完整的XML分析器。本文將告訴你如何構(gòu)建一個輕量級的XML DOM分析程序。
開始編寫SimpleDOMParser
SimpleDOMParser是一個使用Java寫的高度簡化和超輕量級的XML DOM分析器。 你可以將配置整個分析器配置為一個小于4KB的.jar文件。源程序還不到400行呢。
顯然,使用這么小的代碼,SimpleDOMParser將不支持XML域名空間,不能夠理解多字符集編碼或者以DTD文件或者schema驗證文件;但是SimpleDOMParser能做的就是把符合語法規(guī)則的XML標(biāo)記解析為一個類似于DOM的元素樹,讓你執(zhí)行從XML格式化文本提取的數(shù)據(jù)的公共任務(wù)。
為什么使用DOM作為模型而不是SAX呢?這是因為DOM提供一個比SAX更加易用的程序接口。與SAX不同的是,當(dāng)你把一個XML文件作為一個DOM樹來處理的時候,這個文件內(nèi)的所有的信息都是可以利用的。雖然SAX分析模型能夠提供比DOM模型更加優(yōu)異的性能和利用更少的存儲空間,但是大部分開發(fā)者在使用SAX的時候都會發(fā)現(xiàn)他們自己正在創(chuàng)建一個完整的或者部分的DOM樹。使用SAX,一個應(yīng)用程序每次只能處理一條標(biāo)記。如果其它的標(biāo)記內(nèi)容在處理的過程中必須被用到,那你就必須在處理的整個過程保持一種全局狀態(tài)。而保持全局狀態(tài)正是DOM模型目的的精髓。但是許多小型的XML應(yīng)用程序不需要完整的DOM模型。因此,SimpleDOMParser提供到標(biāo)記名、層次和內(nèi)容的訪問,但是不涉及完整的W3C DOM的許多用不上的功能。
簡化DOM模型
一個DOM樹是由分析XML文件產(chǎn)生的結(jié)點組成。結(jié)點是一個XML實體的非存儲表現(xiàn)。標(biāo)準(zhǔn)W3C DOM模型有幾種類型的結(jié)點。 舉例來說,一個文本結(jié)點表示在XML文件中的一段文本,一個元素結(jié)點表示XML文件而一個屬性結(jié)點表示一個元素內(nèi)部的屬性名和值。
DOM是一個樹,因為除了根或文件結(jié)點以外的每個結(jié)點都有一個父結(jié)點。舉例來說,屬性結(jié)點總是和一個元素結(jié)點相關(guān)聯(lián),而用來封裝元素的起始標(biāo)記和結(jié)束標(biāo)記中的文本是映射到一個文本結(jié)點的。文本結(jié)點是元素結(jié)點的一個子節(jié)點。所以,即使很簡單的XML文件的表現(xiàn)也可能會需要很多種節(jié)點類型。舉例來說,圖1表示下面XML文件的一個W3C DOM樹形表示。
<parser>SimpleDOMParser</parser>
正如你在圖1中所看見的,DOM模型使用一個document類型節(jié)點來封裝整個XML文件,所以DOM使用三種不同的節(jié)點。通過把所有的DOM節(jié)點類型抽象成為一個單獨的類型SimpleElement來盡可能的簡化DOM模型。一個SimpleElement獲得一個XML元素的關(guān)鍵的信息,比如標(biāo)識名、元素屬性和任何封裝的文本或者XML。此外,SimpleDOMParser不使用任何特殊的節(jié)點類型表示最高等級的文檔。結(jié)果是大大地簡化了DOM樹,使之只包含SimpleElement節(jié)點。圖2表示了簡化的DOM樹。
代碼段1給出了SimpleElement類的完整的源程序。
public class SimpleElement {
private String tagName;
private String text;
private HashMap attributes;
private LinkedList childElements;
public SimpleElement(String tagName) {
this.tagName = tagName;
attributes = new HashMap();
childElements = new LinkedList();
}
public String getTagName() {
return tagName;
}
public void setTagName(String tagName) {
this.tagName = tagName;
}
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
}
public String getAttribute(String name) {
return (String)attributes.get(name);
}
public void setAttribute(String name, String value) {
attributes.put(name, value);
}
public void addChildElement(SimpleElement element) {
childElements.add(element);
}
public Object[] getChildElements() {
return childElements.toArray();
}
}