轉:java解析xml

來源:互聯網
上載者:User

在平時工作中,難免會遇到把 XML 作為資料存放區格式。面對目前種類繁多的解決方案,哪個最適合我們呢?在這篇文章中,我對這四種主流方案做一個不完全評測,僅僅針對遍曆 XML 這塊來測試,因為遍曆 XML 是工作中使用最多的(至少我認為)。

  預 備

  測試環境:

  AMD 毒龍1.4G OC 1.5G、256M DDR333、Windows2000 Server SP4、Sun JDK 1.4.1+Eclipse 2.1+Resin 2.1.8,在 Debug 模式下測試。

  XML 檔案格式如下:

  <?xml version="1.0" encoding="GB2312"?>
  <RESULT>
  <VALUE>
  <NO>A1234</NO>
  <ADDR>四川省XX縣XX鎮XX路X段XX號</ADDR>
  </VALUE>
  <VALUE>
  <NO>B1234</NO>
  <ADDR>四川省XX市XX鄉XX村XX組</ADDR>
  </VALUE>
  </RESULT>

  測試方法:

 
 採用 JSP
端調用Bean(至於為什麼採用JSP來調用,請參考:http://blog.csdn.net/rosen/archive/2004/10/15
/138324.aspx),讓每一種方案分別解析10K、100K、1000K、10000K的 XML 檔案,計算其消耗時間(單位:毫秒)。

  JSP 檔案:

  <%@ page contentType="text/html; charset=gb2312" %>
  <%@ page import="com.test.*"%>

  <html>
  <body>
  <%
  String args[]={""};
  MyXMLReader.main(args);
  %>
  </body>
  </html>

  測 試

  首先出場的是 DOM(JAXP Crimson 解析器)

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

  另一方面,對於特別大的文檔,解析和載入整個文檔可能很慢且很耗資源,因此使用其他手段來處理這樣的資料會更好。這些基於事件的模型,比如 SAX。

  Bean檔案:

  package com.test;

  import java.io.*;
  import java.util.*;
  import org.w3c.dom.*;
  import javax.xml.parsers.*;

  public class MyXMLReader{

  public static void main(String arge[]){
  long lasting =System.currentTimeMillis();
  try{
   File f=new File("data_10k.xml");
   DocumentBuilderFactory factory=DocumentBuilderFactory.newInstance();
   DocumentBuilder builder=factory.newDocumentBuilder();
   Document doc = builder.parse(f);
   NodeList nl = doc.getElementsByTagName("VALUE");
   for (int i=0;i<nl.getLength();i++){
    System.out.print("車牌號碼:" + doc.getElementsByTagName("NO").item(i).getFirstChild().getNodeValue());
    System.out.println(" 車主地址:" + doc.getElementsByTagName("ADDR").item(i).getFirstChild().getNodeValue());
  }
  }catch(Exception e){
   e.printStackTrace();
  }
  System.out.println("已耗用時間:"+(System.currentTimeMillis() - lasting)+" 毫秒");
  }
  }

  10k消耗時間:265 203 219 172
  100k消耗時間:9172 9016 8891 9000
  1000k消耗時間:691719 675407 708375 739656
  10000k消耗時間:OutOfMemoryError

  接著是 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 解析器的時候編碼工作會比較困難,而且很難同時訪問同一個文檔中的多處不同資料。

  Bean檔案:

  package com.test;
  import org.xml.sax.*;
  import org.xml.sax.helpers.*;
  import javax.xml.parsers.*;

  public class MyXMLReader extends DefaultHandler {

  java.util.Stack tags = new java.util.Stack();

  public MyXMLReader() {
  super();
  }

  public static void main(String args[]) {
  long lasting = System.currentTimeMillis();
  try {
   SAXParserFactory sf = SAXParserFactory.newInstance();
   SAXParser sp = sf.newSAXParser();
   MyXMLReader reader = new MyXMLReader();
   sp.parse(new InputSource("data_10k.xml"), reader);
  } catch (Exception e) {
   e.printStackTrace();
  }
  System.out.println("已耗用時間:" + (System.currentTimeMillis() - lasting) + " 毫秒");
  }

  public void characters(char ch[], int start, int length) throws SAXException {
  String tag = (String) tags.peek();
  if (tag.equals("NO")) {
   System.out.print("車牌號碼:" + new String(ch, start, length));
  }
  if (tag.equals("ADDR")) {
  System.out.println(" 地址:" + new String(ch, start, length));
  }
  }

  public void startElement(
  String uri,
  String localName,
  String qName,
  Attributes attrs) {
  tags.push(qName);
  }
  }

  10k消耗時間:110 47 109 78
  100k消耗時間:344 406 375 422
  1000k消耗時間:3234 3281 3688 3312
  10000k消耗時間:32578 34313 31797 31890 30328

  然後是 JDOM http://www.jdom.org/

 
 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
許可證變體下發布的開放源碼。

  Bean檔案:

  package com.test;

  import java.io.*;
  import java.util.*;
  import org.jdom.*;
  import org.jdom.input.*;

  public class MyXMLReader {

  public static void main(String arge[]) {
  long lasting = System.currentTimeMillis();
  try {
   SAXBuilder builder = new SAXBuilder();
   Document doc = builder.build(new File("data_10k.xml"));
   Element foo = doc.getRootElement();
   List allChildren = foo.getChildren();
   for(int i=0;i<allChildren.size();i++) {
    System.out.print("車牌號碼:" + ((Element)allChildren.get(i)).getChild("NO").getText());
    System.out.println(" 車主地址:" + ((Element)allChildren.get(i)).getChild("ADDR").getText());
   }
  } catch (Exception e) {
   e.printStackTrace();
  }
  System.out.println("已耗用時間:" + (System.currentTimeMillis() - lasting) + " 毫秒");
  }
  }

  10k消耗時間:125 62 187 94
  100k消耗時間:704 625 640 766
  1000k消耗時間:27984 30750 27859 30656
  10000k消耗時間:OutOfMemoryError

  最後是 DOM4J http://dom4j.sourceforge.net/

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

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

  在添加靈活性、XPath 整合和對大文檔處理的目標時,DOM4J
的目標與 JDOM 是一樣的:針對 Java 開發人員的易用性和直觀操作。它還致力於成為比 JDOM 更完整的解決方案,實現在本質上處理所有
Java/XML 問題的目標。在完成該目標時,它比 JDOM 更少強調防止不正確的應用程式行為。

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

  Bean檔案:

  package com.test;

  import java.io.*;
  import java.util.*;
  import org.dom4j.*;
  import org.dom4j.io.*;

  public class MyXMLReader {

  public static void main(String arge[]) {
  long lasting = System.currentTimeMillis();
  try {
   File f = new File("data_10k.xml");
   SAXReader reader = new SAXReader();
   Document doc = reader.read(f);
   Element root = doc.getRootElement();
   Element foo;
   for (Iterator i = root.elementIterator("VALUE"); i.hasNext();) {
    foo = (Element) i.next();
    System.out.print("車牌號碼:" + foo.elementText("NO"));
    System.out.println(" 車主地址:" + foo.elementText("ADDR"));
   }
  } catch (Exception e) {
   e.printStackTrace();
  }
  System.out.println("已耗用時間:" + (System.currentTimeMillis() - lasting) + " 毫秒");
  }
  }

  10k消耗時間:109 78 109 31
  100k消耗時間:297 359 172 312
  1000k消耗時間:2281 2359 2344 2469
  10000k消耗時間:20938 19922 20031 21078

 
 JDOM 和 DOM 在效能測試時表現不佳,在測試 10M 文檔時記憶體溢出。在小文檔情況下還值得考慮使用 DOM 和 JDOM。雖然 JDOM
的開發人員已經說明他們期望在正式發行版前專註效能問題,但是從效能觀點來看,它確實沒有值得推薦之處。另外,DOM 仍是一個非常好的選擇。DOM
實現廣泛應用於多種程式設計語言。它還是許多其它與 XML 相關的標準的基礎,因為它正式獲得 W3C 推薦(與基於非標準的 Java
模型相對),所以在某些類型的項目中可能也需要它(如在 JavaScript 中使用 DOM)。

  SAX表現較好,這要依賴於它特定的解析方式。一個 SAX 檢測即將到來的XML流,但並沒有載入到記憶體(當然當XML流被讀入時,會有部分文檔暫時隱藏在記憶體中)。

  無疑,DOM4J是這場測試的獲勝者,目前許多開源項目中大量採用 DOM4J,例如大名鼎鼎的 Hibernate 也用 DOM4J 來讀取 XML 設定檔。如果不考慮可移植性,那就採用DOM4J吧!

來源:http://www.it.com.cn/f/edu/053/27/93819.htm

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.