java中四種操作(DOM、SAX、JDOM、DOM4J)xml方式詳解與比較
1.詳解
1)DOM(JAXP Crimson解析器)
DOM是用與平臺和語言無關的方式表示XML文件的官方W3C標準。DOM是以層次結構組織的節點或資訊片斷的集合。這個層次結構允許開發人員在樹中尋找特定資訊。分析該結構通常需要載入整個文件和構造層次結構,然後才能做任何工作。由於它是基於資訊層次的,因而DOM被認為是基於樹或基於物件的。DOM以及廣義的基於樹的處理具有幾個優點。首先,由於樹在記憶體中是持久的,因此可以修改它以便應用程式能對資料和結構作出更改。它還可以在任何時候在樹中上下導航,而不是像SAX那樣是一次性的處理。DOM使用起來也要簡單得多。
2)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解析器的時候編碼工作會比較困難,而且很難同時訪問同一個文件中的多處不同資料。
3)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許可證變體下發布的開放原始碼。
4)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.
2。比較
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流被讀入時,會有部分文件暫時隱藏在記憶體中)。
3. 四種xml操作方式的基本使用方法
xml檔案:
- <?xml version="1.0" encoding="gbk"?><list><node><name>weidewei</name><space>http://wishlife.iteye.com</space></node><node><name>flying</name><space>http://user.qzone.qq.com/94611981</space></node></list>
<?xml version="1.0" encoding="gbk"?><list><node><name>weidewei</name><space>http://wishlife.iteye.com</space></node><node><name>flying</name><space>http://user.qzone.qq.com/94611981</space></node></list>
程式程式碼:
- import java.io.File;
- import java.util.Iterator;
- import java.util.List;
- import javax.xml.parsers.DocumentBuilder;
- import javax.xml.parsers.DocumentBuilderFactory;
- import javax.xml.parsers.SAXParser;
- import javax.xml.parsers.SAXParserFactory;
- import org.dom4j.io.SAXReader;
- import org.jdom.Element;
- import org.jdom.input.SAXBuilder;
- import org.w3c.dom.Document;
- import org.w3c.dom.NodeList;
- import org.xml.sax.Attributes;
- import org.xml.sax.InputSource;
- import org.xml.sax.SAXException;
- import org.xml.sax.helpers.DefaultHandler;
- public class MyXMLReader extends DefaultHandler {
- java.util.Stack tags = new java.util.Stack();
- public MyXMLReader() {
- super();
- }
- /**
- * DOM方式
- * @since V2.0
- * @author David.Wei
- * @date 2008-4-11
- * @return void
- */
- public void DOM() {
- long lasting = System.currentTimeMillis();
- try {
- File f = new File("F:/xmltest.xml");
- DocumentBuilderFactory factory = DocumentBuilderFactory
- .newInstance();
- DocumentBuilder builder = factory.newDocumentBuilder();
- Document doc = builder.parse(f);
- NodeList nl = doc.getElementsByTagName("node");
- for (int i = 0; i < nl.getLength(); i++) {
- System.out.println("|| Name: |"
- + doc.getElementsByTagName("name").item(i)
- .getFirstChild().getNodeValue());
- System.out.println("||Space: |"
- + doc.getElementsByTagName("space").item(i)
- .getFirstChild().getNodeValue());
- System.out.println("-------------------------------------------------"); }
- } catch (Exception e) {
- e.printStackTrace();
- }
- System.out.println("DOM RUNTIME:"
- + (System.currentTimeMillis() - lasting) + " MS");
- }
- /**
- * SAX方式
- * @since V2.0
- * @author David.Wei
- * @date 2008-4-11
- * @return void
- */
- public void SAX() {
- long lasting = System.currentTimeMillis();
- try {
- SAXParserFactory sf = SAXParserFactory.newInstance();
- SAXParser sp = sf.newSAXParser();
- MyXMLReader reader = new MyXMLReader();
- sp.parse(new InputSource("F:/xmltest.xml"), reader);
- } catch (Exception e) {
- e.printStackTrace();
- }
- System.out.println("SAX RUNTIME:"
- + (System.currentTimeMillis() - lasting) + " MS");
- }
- public void startElement(String uri, String localName, String qName,
- Attributes attrs) {
- tags.push(qName);
- }
- public void characters(char ch[], int start, int length)
- throws SAXException {
- String tag = (String) tags.peek();
- if (tag.equals("name")) {
- System.out.println("|| Name: |" + new String(ch, start, length));
- }
- if (tag.equals("space")) {
- System.out.println("||Space: |" + new String(ch, start, length));
- }
- System.out.println("-------------------------------------------------");
- }
- /**
- * JDOM方式
- * @since V2.0
- * @author David.Wei
- * @date 2008-4-11
- * @return void
- */
- public void JDOM() {
- long lasting = System.currentTimeMillis();
- try {
- SAXBuilder builder = new SAXBuilder();
- org.jdom.Document doc = builder.build(new File("F:/xmltest.xml"));
- Element foo = doc.getRootElement();
- List allChildren = foo.getChildren();
- for (int i = 0; i < allChildren.size(); i++) {
- System.out.println("|| Name: |"
- + ((Element) allChildren.get(i)).getChild("name")
- .getText());
- System.out.println("||Space: |"
- + ((Element) allChildren.get(i)).getChild("space")
- .getText());
- System.out.println("-------------------------------------------------"); }
- } catch (Exception e) {
- e.printStackTrace();
- }
- System.out.println("JDOM RUNTIME:"
- + (System.currentTimeMillis() - lasting) + " MS");
- }
- /**
- * DOM4J方式
- * @since V2.0
- * @author David.Wei
- * @date 2008-4-11
- * @return void
- */
- public void DOM4J() {
- long lasting = System.currentTimeMillis();
- try {
- File f = new File("F:/xmltest.xml");
- SAXReader reader = new SAXReader();
- org.dom4j.Document doc = reader.read(f);
- org.dom4j.Element root = doc.getRootElement();
- org.dom4j.Element foo;
- for (Iterator i = root.elementIterator("node"); i.hasNext();) {
- foo = (org.dom4j.Element) i.next();
- System.out.println("|| Name: |" + foo.elementText("name"));
- System.out.println("||Space: |" + foo.elementText("space"));
- System.out.println("-------------------------------------------------");
- }
- } catch (Exception e) {
- e.printStackTrace();
- }
- System.out.println("DOM4J RUNTIME:"
- + (System.currentTimeMillis() - lasting) + " MS");
- }
- public static void main(String arge[]) {
- MyXMLReader myXML = new MyXMLReader();
- System.out.println("=====================DOM=========================");
- myXML.DOM();
- System.out.println("=====================SAX=========================");
- myXML.SAX();
- System.out.println("=====================JDOM========================");
- myXML.JDOM();
- System.out.println("=====================DOM4J=======================");
- myXML.DOM4J();
- System.out.println("=================================================");
- }
- }
import java.io.File;
import java.util.Iterator;
import java.util.List;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import org.dom4j.io.SAXReader;
import org.jdom.Element;
import org.jdom.input.SAXBuilder;
import org.w3c.dom.Document;
import org.w3c.dom.NodeList;
import org.xml.sax.Attributes;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
public class MyXMLReader extends DefaultHandler {
java.util.Stack tags = new java.util.Stack();
public MyXMLReader() {
super();
}
/**
* DOM方式
* @since V2.0
* @author David.Wei
* @date 2008-4-11
* @return void
*/
public void DOM() {
long lasting = System.currentTimeMillis();
try {
File f = new File("F:/xmltest.xml");
DocumentBuilderFactory factory = DocumentBuilderFactory
.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document doc = builder.parse(f);
NodeList nl = doc.getElementsByTagName("node");
for (int i = 0; i < nl.getLength(); i++) {
System.out.println("|| Name: |"
+ doc.getElementsByTagName("name").item(i)
.getFirstChild().getNodeValue());
System.out.println("||Space: |"
+ doc.getElementsByTagName("space").item(i)
.getFirstChild().getNodeValue());
System.out.println("-------------------------------------------------"); }
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("DOM RUNTIME:"
+ (System.currentTimeMillis() - lasting) + " MS");
}
/**
* SAX方式
* @since V2.0
* @author David.Wei
* @date 2008-4-11
* @return void
*/
public void SAX() {
long lasting = System.currentTimeMillis();
try {
SAXParserFactory sf = SAXParserFactory.newInstance();
SAXParser sp = sf.newSAXParser();
MyXMLReader reader = new MyXMLReader();
sp.parse(new InputSource("F:/xmltest.xml"), reader);
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("SAX RUNTIME:"
+ (System.currentTimeMillis() - lasting) + " MS");
}
public void startElement(String uri, String localName, String qName,
Attributes attrs) {
tags.push(qName);
}
public void characters(char ch[], int start, int length)
throws SAXException {
String tag = (String) tags.peek();
if (tag.equals("name")) {
System.out.println("|| Name: |" + new String(ch, start, length));
}
if (tag.equals("space")) {
System.out.println("||Space: |" + new String(ch, start, length));
}
System.out.println("-------------------------------------------------");
}
/**
* JDOM方式
* @since V2.0
* @author David.Wei
* @date 2008-4-11
* @return void
*/
public void JDOM() {
long lasting = System.currentTimeMillis();
try {
SAXBuilder builder = new SAXBuilder();
org.jdom.Document doc = builder.build(new File("F:/xmltest.xml"));
Element foo = doc.getRootElement();
List allChildren = foo.getChildren();
for (int i = 0; i < allChildren.size(); i++) {
System.out.println("|| Name: |"
+ ((Element) allChildren.get(i)).getChild("name")
.getText());
System.out.println("||Space: |"
+ ((Element) allChildren.get(i)).getChild("space")
.getText());
System.out.println("-------------------------------------------------"); }
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("JDOM RUNTIME:"
+ (System.currentTimeMillis() - lasting) + " MS");
}
/**
* DOM4J方式
* @since V2.0
* @author David.Wei
* @date 2008-4-11
* @return void
*/
public void DOM4J() {
long lasting = System.currentTimeMillis();
try {
File f = new File("F:/xmltest.xml");
SAXReader reader = new SAXReader();
org.dom4j.Document doc = reader.read(f);
org.dom4j.Element root = doc.getRootElement();
org.dom4j.Element foo;
for (Iterator i = root.elementIterator("node"); i.hasNext();) {
foo = (org.dom4j.Element) i.next();
System.out.println("|| Name: |" + foo.elementText("name"));
System.out.println("||Space: |" + foo.elementText("space"));
System.out.println("-------------------------------------------------");
}
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("DOM4J RUNTIME:"
+ (System.currentTimeMillis() - lasting) + " MS");
}
public static void main(String arge[]) {
MyXMLReader myXML = new MyXMLReader();
System.out.println("=====================DOM=========================");
myXML.DOM();
System.out.println("=====================SAX=========================");
myXML.SAX();
System.out.println("=====================JDOM========================");
myXML.JDOM();
System.out.println("=====================DOM4J=======================");
myXML.DOM4J();
System.out.println("=================================================");
}
}
執行結果:
- =====================DOM=========================
- || Name: |weidewei
- ||Space: |http://wishlife.iteye.com
- -------------------------------------------------
- || Name: |flying
- ||Space: |http://user.qzone.qq.com/94611981
- -------------------------------------------------
- DOM RUNTIME:62 MS
- =====================SAX=========================
- || Name: |weidewei
- -------------------------------------------------
- ||Space: |http://wishlife.iteye.com
- -------------------------------------------------
- || Name: |flying
- -------------------------------------------------
- ||Space: |http://user.qzone.qq.com/94611981
- -------------------------------------------------
- SAX RUNTIME:16 MS
- =====================JDOM========================
- || Name: |weidewei
- ||Space: |http://wishlife.iteye.com
- -------------------------------------------------
- || Name: |flying
- ||Space: |http://user.qzone.qq.com/94611981
- -------------------------------------------------
- JDOM RUNTIME:78 MS
- =====================DOM4J=======================
- || Name: |weidewei
- ||Space: |http://wishlife.iteye.com
- -------------------------------------------------
- || Name: |flying
- ||Space: |http://user.qzone.qq.com/94611981
- -------------------------------------------------
- DOM4J RUNTIME:78 MS
- =================================================
執行時如果有錯誤可能原因(我碰到的就這兩個,解決了就OK了):
1.錯誤現象: Caused by: org.xml.sax.SAXParseException: Content is not allowed in prolog.
解決辦法:xml檔案換行問題,編寫xml檔案時不要換行就可以了.
2.dom4j
錯誤現象: org.dom4j.DocumentException: Error on line 1 of document : Content is not allowed in prolog.
解決方法:dom4j的jar包使用dom4j1.6就可以了.
相關文章
- XML和Dom4jXML
- java的XML解析(DOM4J技術)JavaXML
- Java中陣列判斷元素存在幾種方式比較詳解Java陣列
- XML解析-最快的方式SAXXML
- dom4j遍歷巢狀xml巢狀XML
- 探索多種資料格式:JSON、YAML、XML、CSV等資料格式詳解與比較JSONYAMLXML
- DOM4J 解析 XML 之忽略轉義字元XML字元
- jdom解析xml檔案XML
- PHP操作xml詳解PHPXML
- react之四種元件中DOM樣式設定方式React元件
- SpringDI四種依賴注入方式詳解Spring依賴注入
- Java中強、軟、弱、虛四種引用詳解Java
- PHP透過DOM操作XMLPHPXML
- Java字串建立方式比較Java字串
- Java中的字串操作(比較String,StringBuiler和StringBuffer)Java字串UI
- Java集合詳解3:Iterator,fail-fast機制與比較器JavaAIAST
- 使用jaxp解析器dom方式對xml節點進行操作XML
- Java中CompletableFuture的thenApply與thenApplyAsync比較JavaAPP
- 類與介面(二)java的四種內部類詳解Java
- 獲取或操作DOM元素特性的幾種方式
- 四種在Javascript比較物件的方法JavaScript物件
- JS嵌入html的方式及各種方式的比較JSHTML
- Spring系列第四講 xml中bean定義詳解SpringXMLBean
- mongodb資料遷移2種方式比較MongoDB
- Java 動態代理原理圖解 (附:2種實現方式詳細對比)Java圖解
- Java建立陣列、賦值的四種方式,宣告+建立+初始化 詳解Java陣列賦值
- Spring中基於XML方式的AOP操作SpringXML
- dom解析和sax解析的區別
- 詳解vue 路由跳轉四種方式 (帶引數)Vue路由
- MyBatis 與 SpringBoot 整合:註解和xml兩種使用方式介紹MyBatisSpring BootXML
- Java 建立類的四種方式Java
- 【超好用API推薦】用dom4j建立XML檔案並寫入節點APIXML
- Java中CompletableFuture與虛擬執行緒比較Java執行緒
- BOM與DOM之DOM操作
- Java中的幾種Kafka客戶端比較介紹JavaKafka客戶端
- java--執行緒池--建立執行緒池的幾種方式與執行緒池操作詳解Java執行緒
- jaxp的sax解析操作
- Java幾種常用JSON庫效能比較JavaJSON
- python執行系統命令四種方法比較Python