XML的DOM解析器的java實現(三) 類設計
類設計
軟件中起關鍵作用的類為CharCollector字符收集器類、SimpleDOMParser解析內核類和Manager中間層控制類。
字符收集器類
字符收集器類是軟件的底層類,它與XML文件交互,讀取文件中的字符信息,經過處理,形成標簽,文本,屬性等數據為上層提供服務。
成員變量介紹:
aReader:Reader對象,輸入流為文件輸入流,它將XML文件的字符數據以流的形式提供給類。
成員方法介紹:
comparedArray(): 輸入:兩個int型數組,輸出:boolean型,返回兩個數組是否相同。用于比較兩個數組是否相同,在方法中,對兩個數組的數逐一比較。
hasMoreChars(): 輸入:無,輸出:boolean型,表示文件中是否還有字符,該方法用于確定文件中是否還有字符。
peek(): 輸入:int型數組。用于存儲窺探到的字符,輸出:無,該方法用于從文件中窺探數組長度的字符數據。窺探就是從文件中讀取數據后,將輸入流標記回以前的位置,以免丟失數據。
算法簡述:
在aReader上標記數組的長度
aReader.mark(buffer.length);
2、將數據依次讀入數組
for (int i = 0; i < buffer.length; i++) {
buffer[i] = aReader.read();
}
恢復aReader
aReader.reset();
peek(): 輸入:無,輸出:int型,是窺探到的字符,該方法從文件中窺探一個字符數據。
processCDATA(): 輸入:StringBuffer型,用于存放CDATA數據,輸出:無,用于處理XML文件中的CDATA節點。得到的CDATA節點存放到StringBuffer對象中。
算法簡述:
預設兩個數組
int[] cdataHead = {'<', '!', '[', 'C', 'D', 'A', 'T', 'A', '['};
int[] cdataTail = {']', ']', '>'};
窺探cdataHead長度的字符存在數組buf中
peek(buf);
比較buf與cdataHead數組的內容是否相同,如果不同返回falase,如果相同繼續執行。
將aReader跳過cdataHead的長度,然后循環讀取直到窺探的字符數組與cdataTail相同,將中間的字符存放到StringBuffer對象中。
while (true) {
peek(buf);
if (comparedArray(buf, cdataTail)) {
aReader.skip(cdataTail.length);
flag = true;
break;
} else {
bufChar = aReader.read();
if (bufChar == -1) {
throw new IOException("CDATA node without end tag");
}
sb.append((char) bufChar);
}
}
processEntity(): 輸入:StringBuffer型,用于存放實體數據,輸出:無,用語處理XML文件中的內建實體類型。得到的實體存放到StringBuffer對象中。
readTag(): 輸入:無,輸出:String型,是讀到的標簽,從XML文件中讀取并整理成一個標簽數據存放在String對象中。
算法簡述:
窺探一個字符,如果不是’<’,拋出異常。否則繼續執行。
int nextChar = peek();
if (nextChar != '<') {
throw new IOException("expect '<',but got '" + (char) nextChar +"'");
}
窺探一個字符aChar
int aChar = peek();
如果字符為’<’,進行CDATA節點處理
if (aChar == '<') {
if (processCDATA(sb)) {
aChar = peek();
continue;
}
}
如果字符為’&’,進行內建實體處理
if (aChar == '&') {
if (processEntity(sb)) {
aChar = peek();
continue;
}
}
如果字符為’>’或文件結束,返回StringBuffer對象。
如果是其它字符,加入到StringBuffer對象中。
readText(): 輸入:無,輸出:String型,是讀到的文本內容,從XML文件中讀取并整理成一個文本數據存放在Sting對象中。
skipOtherTag(): 輸入:無,輸出:無,跳過一個不處理的標簽。
skipOtherTags(): 輸入:無,輸出:無,跳過多個不處理的標簽。
skipWhitespace():輸入:無,輸出:無,跳過空格。
解析內核類
該類用于解析XML文件,包含parser()方法,是該類的核心方法。
成員變量介紹:
aCharCollector:CharCollector類對象,負責字符收集。
currentNode: SimpleElement類對象,表示當前處理的元素。
Elements: Stack類對象,用棧的存儲結構,表示元素之間的層次關系。
成員方法介紹:
Parser(): 輸入:無,輸出:SimpleDocument類對象,是返回的整個文檔樹型結構。
算法簡述:
1、讀取一個標簽
2、判斷是開始標簽還是結束標簽,如果是結束標簽,轉入結束標簽處理3
如果是開始標簽,轉入開始標簽處理6
3、得到標簽的名稱,判斷是否與currentNode的名稱相同,如果相同,執行
4,否則拋出異常
4、判斷是否還有標簽,如果有繼續執行5,否則退出。
5、從棧中彈出一個節點給currentNode,執行1
6、得到標簽的名稱,屬性,文本內容,將標簽加入到DOM樹中,并且壓棧。
執行1
算法的程序流程圖
中間層管理類
中間層管理類用于控制和協調解析器與用戶界面。
成員變量介紹:
isParsered: boolean型,判斷是否已經解析過了。
document: SimpleDocument型對象,表示整個XML文檔樹,也是解析器返回的。
parser: SimpleDOMParser型對象,表示解析器。
成員方法介紹:
getTreeRoot(): 輸入:無,輸出:DefaultMutableTreeNode型對象,是得到的樹的根節點,用于得到樹的根節點。
parser(): 輸入:無,輸出:無,用于執行解析操作。
setInputStream(): 輸入:InputStream型對象,是要設置的輸入流,輸出:無,用于設置解析源。
setXMLFile(): 輸入:File型對象,是要設置的XML文件,輸出:無,用于設置XML文件源。
getTreeNode(): 輸入:SimpleElement型對象,是要轉換的對象,輸出:DefaultMutableTreeNode型對象,是轉換后的對象,用
于轉換相應元素為樹的節點對象。
posted on 2007-05-31 11:32 Rex Mao 閱讀(1187) 評論(0) 編輯 收藏 所屬分類: 技術