程式扎記: [ Java 文章收集 ] Java中四種操作xml方式的比較

標籤

2012年8月1日 星期三

[ Java 文章收集 ] Java中四種操作xml方式的比較


來源自 這裡
DOM(JAXP Crimson解析器):
DOM是用與平臺和語言無關的方式表示XML文檔的官方W3C標準。DOM是以層次結構組織的節點或資訊片斷的集合。這個層次結構允許開發人員在樹中尋找特定資訊。分析該結構通常需要載入整個文檔和構造層次結構,然後才能做任何工作。由於它是基於資訊層次的,因而DOM被認為是基於樹或基於物件的。DOM以及廣義的基於樹的處理具有幾個優點。首先,由於樹在記憶體中是持久的,因此可以修改它以便應用程式能對資料和結構作出更改。它還可以在任何時候在樹中上下導航,而不是像SAX那樣是一次性的處理。DOM使用起來也要簡單得多.

SAX :
SAX處理的優點非常類似於流媒體的優點。分析能夠立即開始,而不是等待所有的資料被處理。而且,由於應用程式只是在讀取資料時檢查資料,因此不需要將資料存儲在記憶體中。這對於大型文檔來說是個巨大的優點。事實上,應用程式甚至不必解析整個文檔;它可以在某個條件得到滿足時停止解析。一般來說,SAX還比它的替代者DOM快許多.選擇DOM還是選擇SAX? 對於需要自己編寫代碼來處理XML文檔的開發人員來說, 選擇DOM還是SAX解析模型是一個非常重要的設計決策。 DOM採用建立樹形結構的方式訪問XML文檔,而SAX採用的事件模型.

DOM解析器把XML文檔轉化為一個包含其內容的樹,並可以對樹進行遍曆。用DOM解析模型的優點是編程容易,開發人員只需要調用建樹的指令,然後利用navigation APIs訪問所需的樹節點來完成任務。可以很容易的添加和修改樹中的元素。然而由於使用DOM解析器的時候需要處理整個XML文檔,所以對性能和記憶體的要求比較高,尤其是遇到很大的XML檔的時候。由於它的遍曆能力,DOM解析器常用于XML文檔需要頻繁的改變的服務中.

SAX解析器採用了基於事件的模型,它在解析XML文檔的時候可以觸發一系列的事件,當發現給定的tag的時候,它可以啟動一個回調方法,告訴該方法制定的標籤已經找到。SAX對記憶體的要求通常會比較低,因為它讓開發人員自己來決定所要處理的tag.特別是當開發人員只需要處理文檔中所包含的部分資料時,SAX這種擴展能力得到了更好的體現。但用SAX解析器的時候編碼工作會比較困難,而且很難同時訪問同一個文檔中的多處不同資料.

JDOM :
JDOM的目的是成為Java特定文檔模型,它簡化與XML的交互並且比使用DOM實現更快。由於是第一個Java特定模型,JDOM一直得到大力推廣和促進。正在考慮通過"Java規範請求JSR-102"將它最終用作"Java標準擴展"。從2000年初就已經開始了JDOM開發. JDOM與DOM主要有兩方面不同。首先,JDOM僅使用具體類而不使用介面。這在某些方面簡化了API,但是也限制了靈活性。第二,API大量使用了Collections類,簡化了那些已經熟悉這些類的Java開發者的使用.

JDOM文檔聲明其目的是"使用20%(或更少)的精力解決80%(或更多)Java/XML問題"(根據學習曲線假定為20%)。JDOM對於大多數Java/XML應用程式來說當然是有用的,並且大多數開發者發現API比DOM容易理解得多。JDOM還包括對程式列為的相當廣泛檢查以防止用戶做任何在XML中無意義的事。然而,它仍需要您充分理解XML以便做一些超出基本的工作(或者甚至理解某些情況下的錯誤)。這也許是比學習DOM或JDOM介面都更有意義的工作.

JDOM自身不包含解析器。它通常使用SAX2解析器來解析和驗證輸入XML文檔(儘管它還可以將以前構造的DOM表示作為輸入)。它包含一些轉換器以將JDOM表示輸出成SAX2事件流、DOM模型或XML文本文檔。JDOM是在Apache許可證變體下發佈的開放源碼.

DOM4J :
雖然DOM4J代表了完全獨立的開發結果,但最初,它是JDOM的一種智慧分支。它合併了許多超出基本XML文檔表示的功能,包括集成的XPath支持、XML Schema支援以及用於大文檔或流化文檔的基於事件的處理。它還提供了構建文檔表示的選項,它通過DOM4J API和標準DOM介面具有並行訪問功能。從2000下半年開始,它就一直處於開發之中.

為支援所有這些功能,DOM4J使用介面和抽象基本類方法。DOM4J大量使用了API中的Collections類,但是在許多情況下,它還提供一些替代方法以允許更好的性能或更直接的編碼方法。直接好處是,雖然DOM4J付出了更複雜的API的代價,但是它提供了比JDOM大得多的靈活性.

DOM4J是一個非常非常優秀的Java XML API,具有性能優異、功能強大和極端易用使用的特點,同時它也是一個開放源代碼的軟體。如今你可以看到越來越多的Java軟體都在使用DOM4J來讀寫XML,特別值得一提的是連Sun的JAXM也在用DOM4J.

上述 XML 使用比較 :
1. DOM4J性能最好,連Sun的JAXM也在用DOM4J.目前許多開源專案中大量採用DOM4J,例如大名鼎鼎的Hibernate也用DOM4J來讀取XML配置檔。如果不考慮可攜性,那就採用DOM4J.
2. JDOM和DOM在性能測試時表現不佳,在測試10M文檔時記憶體溢出。在小文檔情況下還值得考慮使用DOM和JDOM.雖然JDOM的開發者已經說明他們期望在正式發行版前專注性能問題,但是從性能觀點來看,它確實沒有值得推薦之處。另外,DOM仍是一個非常好的選擇。DOM實現廣泛應用於多種編程語言。它還是許多其他與XML相關的標準的基礎,因為它正式獲得W3C推薦(與基於非標準的Java模型相對),所以在某些類型的專案中可能也需要它(如在JavaScript中使用DOM)。
3. SAX表現較好,這要依賴於它特定的解析方式-事件驅動。一個SAX檢測即將到來的XML流,但並沒有載入到記憶體(當然當XML流被讀入時,會有部分文檔暫時隱藏在記憶體中)。

範例代碼 :
考慮有如下的 XML 檔案 :




- DOM 範例

  1. package xml;  
  2.   
  3. import java.io.*;  
  4. import java.util.*;  
  5. import org.w3c.dom.*;  
  6. import javax.xml.parsers.*;  
  7.   
  8. public class DOMEx {  
  9.     public static void main(String arge[]) {  
  10.         long lasting = System.currentTimeMillis();  
  11.         try {  
  12.             File f = new File("test.xml");  
  13.             DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();  
  14.             DocumentBuilder builder = factory.newDocumentBuilder();  
  15.             Document doc = builder.parse(f);  
  16.             NodeList nl = doc.getElementsByTagName("VALUE");  
  17.             for (int i = 0; i < nl.getLength(); i++) {  
  18.                 System.out.print("車牌號碼:" + doc.getElementsByTagName("NO").item(i).getFirstChild().getNodeValue());  
  19.                 System.out.println("車主地址:" + doc.getElementsByTagName("ADDR").item(i).getFirstChild().getNodeValue());  
  20.             }  
  21.         } catch (Exception e) {  
  22.             e.printStackTrace();  
  23.         }  
  24.         System.out.println("運行時間:" + (System.currentTimeMillis() - lasting) + "毫秒");  
  25.     }  
  26. }  
- SAX 範例
  1. package xml;  
  2.   
  3. import org.xml.sax.*;   
  4. import org.xml.sax.helpers.*;   
  5. import javax.xml.parsers.*;   
  6.   
  7. public class SAXEx extends DefaultHandler {  
  8.     java.util.Stack tags = new java.util.Stack();   
  9.   
  10.     /** 
  11.      * @param args 
  12.      */  
  13.     public static void main(String[] args) {  
  14.         long lasting = System.currentTimeMillis();   
  15.         try {   
  16.             SAXParserFactory sf = SAXParserFactory.newInstance();   
  17.             SAXParser sp = sf.newSAXParser();   
  18.             SAXEx reader = new SAXEx();   
  19.             sp.parse(new InputSource("test.xml"), reader);   
  20.         } catch (Exception e) {   
  21.             e.printStackTrace();   
  22.         }  
  23.   
  24.         System.out.println("運行時間:" + (System.currentTimeMillis() - lasting) + "毫秒");  
  25.     }   
  26.       
  27.     @Override  
  28.     public void characters(char ch[], int start, int length) throws SAXException {   
  29.         if(tags.isEmpty()) return;  
  30.         String tag = (String) tags.pop();   
  31.         if (tag.equals("NO")) {   
  32.             System.out.print("車牌號碼:" + new String(ch, start, length));   
  33.         }   
  34.         if (tag.equals("ADDR")) {   
  35.             System.out.println(", 地址:" + new String(ch, start, length));   
  36.         }   
  37.     }  
  38.   
  39.     public void startElement(String uri,String localName,String qName,Attributes attrs) {   
  40.         tags.push(qName);  
  41.     }   
  42. }  
- JDOM 範例
這裡的範例需要另外下載 JDOM Library 的 package, 可以到 jdom.org 上的下載頁面找到. 並加入到你的 Classpath 中.
  1. package xml;  
  2.   
  3. import java.io.*;  
  4. import java.util.*;  
  5. import org.jdom2.*;  
  6. import org.jdom2.input.*;  
  7.   
  8. public class JDOMEx {  
  9.   
  10.     /** 
  11.      * @param args 
  12.      */  
  13.     public static void main(String[] args) {  
  14.         long lasting = System.currentTimeMillis();   
  15.         try{   
  16.             SAXBuilder builder = new SAXBuilder();   
  17.             Document doc = builder.build(new File("test.xml"));   
  18.             Element foo = doc.getRootElement();   
  19.             List allChildren = foo.getChildren();   
  20.             for(int i=0;i < allChildren.size();i++) {   
  21.                 System.out.print("車牌號碼:" + ((Element)allChildren.get(i)).getChild("NO").getText());   
  22.                 System.out.println("車主地址:" + ((Element)allChildren.get(i)).getChild("ADDR").getText());  
  23.             }   
  24.         } catch (Exception e) {   
  25.             e.printStackTrace();   
  26.         }  
  27.         System.out.println("JDOMEx 運行時間:" + (System.currentTimeMillis() - lasting) + "毫秒");  
  28.     }  
  29. }  
- DOM4J 範例
dom4j 的 library 可以到 這裡 下載. 範例代碼如下 :
  1. package xml;  
  2.   
  3. import java.io.*;  
  4. import java.util.*;  
  5. import org.dom4j.*;  
  6. import org.dom4j.io.*;  
  7.   
  8. public class DOM4JEx {  
  9.   
  10.     /** 
  11.      * @param args 
  12.      */  
  13.     public static void main(String[] args) {  
  14.         long lasting = System.currentTimeMillis();   
  15.         try {   
  16.             File f = new File("test.xml");   
  17.             SAXReader reader = new SAXReader();   
  18.             Document doc = reader.read(f);   
  19.             Element root = doc.getRootElement();   
  20.             Element foo;   
  21.             for (Iterator i = root.elementIterator("VALUE"); i.hasNext();) {   
  22.                 foo = (Element) i.next();   
  23.                 System.out.print("車牌號碼:" + foo.elementText("NO"));   
  24.                 System.out.println("車主地址:" + foo.elementText("ADDR"));   
  25.             }   
  26.         } catch (Exception e) {   
  27.             e.printStackTrace();   
  28.         }   
  29.         System.out.println("Dom4j 運行時間:" + (System.currentTimeMillis() - lasting) + "毫秒");  
  30.     }  
  31. }  

Supplement :
Java API for XML Code Samples
Java API for XML processing (JAXP) lets you access XML documents either serially (SAX) or in random access mode (DOM)...

This message was edited 16 times. Last update was at 01/08/2012 22:48:52

沒有留言:

張貼留言

網誌存檔

關於我自己

我的相片
Where there is a will, there is a way!