enhydra的kxml是乙個只佔很小
儲存空間的xml語法分析程式,對於j2me應用程式非常適合。它有乙個非常獨特的dom操作方法和被稱為pull的語法分析方法。
我最近一直在開發乙個用於j2me裝置的多人遊戲專案。在這個應用程式中,
伺服器和裝置之間的通訊原來被編碼成由"&"分隔的鍵值對,這樣從伺服器檢索變數會很快,但是當我開始處理更複雜的資料結構和巢狀的資料結構時,我發現這種方法並不適用。在這種情況,它會變得很難寫資料並且容易出錯。
為了解決這問題,我決定使用xml重新編寫應用程式的資料傳輸部分。對於我來說,xml是乙個自然而然的選擇,不僅僅因為我已經使用它在以前的乙個專案中編寫了通過網路向
t中傳送
資訊儲存器
中的節點結構,你可以遍歷這棵樹。它非常簡單易用,但是因為整棵樹存在於儲存器中造成儲存器的負擔。
第二種方法在捕捉語法分析事件中,每當語法分析程式遇到資料中的特定結構,它就會遍歷xml資料,然後把結果發回前面註冊的乙個事件***中。比如說,當語法分析程式遇到乙個起始標記,如<html>,那麼事件***將接收乙個事件,通知它這個情況,並且向它傳遞任何所需的資訊。實現這種策略的語法分析程式被稱為push語法分析程式,因為這個語法分析程式把事件"推入"乙個***中。
kxml支援dom語法分析和操作,但是不支援push語法分析。取而代之,它使用一種稍微不同的稱為"pull"的分析方法。與push語法分析相反,pull語法分析讓程式設計師從語法分析程式中"拉"出下乙個事件。在push語法分析中,你必須維護你正在分析的當前資料的狀態,然後基於傳送到***的事件,恢復任何以前的狀態,並且當你轉換到乙個不同的狀態時儲存新的狀態。pull語法分析使處理狀態改變更加容易,因為你可以傳送分析器到不同的函式,維護它們自己的狀態變數。
pull語法分析
讓我們來研究乙個例子,看看kxml如何做乙個pull語法分析程式。演示程式名為kxmldemo_pull。它將使用乙個pull語法分析程式檢視乙個包含通訊錄資訊的檔案。下面給出源**中比較重要的幾行,我還給出了注釋。
1.xmlparser parser = null;
2......
3.parser = new xmlparser( new inputstreamreader( 1this.getclass().getresourceasstream(resfile_name) ));
第三行建立了乙個xmlparser,把它傳到乙個inputstream中。這個語法分析程式反覆呼叫,直到出現end_document事件。
1.while ( (event = parser.read()).gettype() != xml.end_document )
6....
7. parseevent next = parser.read();
8. 9. // if it's not a text event then skip it
10. if (next.gettype() != xml.text)
13....
14. system.err.println(name + ": " + text);
上面的這段**在"parseaddresstag"中迴圈,直到找到與<address>對應的終止標記。如果它遇到其它任何標記,那麼標記名和標記內容就會被列印到控制台上。因此,如果找到標記<name>robert cadena</name>,你將看到下面的控制台輸出:
name: robert cadena
一旦找到<address>的終止標記(8- 10行),控制項被返**用函式,然後又開始查詢<address>。
如你所見,使用pull語法分析程式非常容易,並且能夠傳送語法分析程式到另乙個函式,然後在文件中查詢元素。你並不侷限於分析資源檔案;你還可以使用httpconnection把這個函式傳遞到http inputstream。這把你從讀取inputstream、儲存內容、分析內容等操作中解放了出來,一切都由kxml為你完成。
dom處理
pull語法分析特別適用於當你需要維護非常小的
儲存空間的時候,因為發出事件的文件只有一部分存在於記憶體中。換句話說,如果你感興趣的特定資料段是文件中部的幾百個位元組,那麼前面的幾百個位元組就不必儲存在記憶體中了。
但是如果你能夠節省一些記憶體,你可以使用另乙個版本的kxml語法分析程式,它包含對dom的支援。 dom是儲存在記憶體中的整個文件樹,每個標記都被分離成節點(node)物件。 你可以遍歷這個文件樹,然後根據需要取得資料。
工程中的另乙個midlet,kxmldemo_dom,做了同樣的事情。它讀取乙個通訊錄,然後把內容列印到控制台,但是這次它使用了dom。下面給出源**中比較重要的幾行.
1.document doc = new document();
2....
3.parser = new xmlparser( isr );
4.doc.parse( parser );
第一行建立了乙個文件,儲存xml樹。第三行從乙個名為isr的inputstreamreader中建立乙個kxml語法分析程式。第四行傳送這個語法分析程式到文件,然後讓文件開始分析。xml被遞迴分析,直到到達文件的結尾。當分析呼叫退出時,整個文件被裝入記憶體,這時你就可以操作它了。
1.element root = doc.getrootelement();
2.int child_count = root.getchildcount();
3....
4.for (int i = 0; i < child_count ; i++ )
因為我們知道<address>元素是根元素的直接子元素,我們可以遍歷根元素的子元素,尋找address標記,如果子元素不是乙個address 標記,則返回。
1.int address_item_count = kid.getchildcount();
2. 3. for (int j = 0; j < address_item_count ; j++) {
4....
如果我們找到了address子元素,我們開始遍歷它的子元素,並把這些子元素的內容列印出來。不幸的是,你不能只是使用kid.getelement("name"),因為如果這個元素不存在的話,那麼你將得到乙個runtimeexception。所以我建議只有當你知道xml文件中存在你所有需要的所有欄位時才使用這個方法。
檢查你的記憶體
根據經驗,當你不能確保你的應用程式的結構,並且你需要保持記憶體被占用情況較低時,你應該使用pull語法分析程式。當你有足夠記憶體並且可能需要通過新增或移動標記的方式操作文件時,可以使用dom。
如果你想看看這兩種方法使用記憶體的情況,在k*******中開啟工程,使用記憶體監視器(edit-->preferences:monitoring tag)。 當你執行midlet,你將看到記憶體監控視窗彈出,有圖形和數字表示記憶體的使用情況。 執行每乙個應用程式,然後觀察綠線上公升,這表示你的應用程式消耗的記憶體量。 你將看到pull應用程式比dom應用程式使用記憶體少一些。雖然本例中的兩個midlet之間的區別不是非常大,但是如果乙個midlet用dom方式遍歷乙個更大的檔案,那麼它將消耗更多記憶體。
j2me中kxml解析xml例項 2 xml
陸地交通 vox type name table table vox type 7 vox type vox type name 空中交通 vox type name table table vox type 50 vox type vox type name 娛樂 旅遊 vox type name...
J2ME中的XML解析器
在j2me應用程式中,我們可以使用xml解析器來訪問網路上的基於xml的服務。比如,我們可以通過乙個 的聚合器來定製地顯示某些新聞的標題和內容簡介,這些內容的傳遞都是基於xml的服務。xml解析器的是用目前來說是十分昂貴的,它需要比較大的記憶體以及更多的運算時間要求。為了適應在midp環境下執行,x...
J2ME 的XML 解析器 kXML
kxml是乙個j2me平台下使用的xml語法分析程式,對於j2me應用程式非常適合。它有乙個非常獨特的dom操作方法和被稱為pull的語法分析方法。它有以下特性 支援xml命名空間 用 鬆散 模式分析html或其它sgml格式 占用很少的儲存空間 21 kbps 基於pull的分析 支援xml寫操作...