1. 程式人生 > >sax和dom在解析xml文件時有什麼區別

sax和dom在解析xml文件時有什麼區別

當你需要處理XML文件時,你的首要選擇是使用DOM(文件物件模型)還是使用SAX(用於XML的簡單API),即當前使用的兩個主要的XML API。你可以使用任何一種(或者在同一時間使用兩種)來處理XML文件,然而DOM將文件載入到記憶體中處理,而SAX則相反,它可以檢測一個即將到來的 XML流,由此並不需要所有的XML程式碼同時載入到記憶體中。
選擇DOM與SAX,與在一個數據庫中的表單與檢視之前選擇一樣:選擇適合於當前實際情況的方法。如果你只是想簡單地檢視XML文件而不處理它,那麼請選擇使用SAX。

  SAX與DOM之間的區別


SAX與DOM之間有一些顯著區別,包括:
DOM是複雜物件處理的首選,比如當XML比較複雜的時候,或者當你需要隨機處理文件中資料的時候。SAX從文件的開始通過每一節點移動,以定位一個特定的節點。 


DOM為載入到記憶體的文件節點建立型別描述。最終,這些描述呈現了可容易橫向移動、潛在巨大、樹型結構。如果XML很冗長,DOM就會顯示出無法控制的脹 大。例如,一個300KB的XML文件可以導致RAM或者虛擬記憶體中的3,000,000KB的DOM樹型結構。通過比較就會發現,一個SAX文件根本就 沒有被解構,它也沒有隱藏在記憶體空間中(當然當XML流被讀入時,會有部分文件暫時隱藏在記憶體中)。SAX就是一種“更輕巧的”技術──它可以給你的系統 帶來更輕的負擔。SAX相當於觀看一場馬拉松比賽,而DOM就好比邀請所有的比賽選手到家裡參加晚餐。
所以,你如何選擇SAX和DOM?如果你處理複雜的東西,比如高階XSLT轉換,或者Xpath過濾,請選擇使用DOM。如果你建立或者更改XML文件,你也可以選擇DOM。

相反,你可以使用SAX來查詢或者閱讀XML文件。SAX可以快速掃描一個大型的XML文件,當它找到查詢標準時就會立即停止,然後再處理之。
在某些情況下,在一個方案中,最佳的選擇是使用DOM和SAX處理不同的部分。例如,你可以使用DOM將XML載入到記憶體並改變它,然後通過從DOM樹中傳送一個SAX流而轉移最後的結果。


SAX概念
SAX是Simple API for XML的縮寫,它並不是由W3C官方所提出的標準,可以說是“民間”的事實標準。實際上,它是一種社群性質的討論產物。雖然如此,在XML中對SAX的應用絲毫不比DOM少,幾乎所有的XML解析器都會支援它。

與DOM比較而言,SAX是一種輕量型的方法。我們知道,在處理DOM的時候,我們需要讀入整個的XML文件,然後在記憶體中建立DOM樹,生成 DOM樹上的每個Node物件。當文件比較小的時候,這不會造成什麼問題,但是一旦文件大起來,處理DOM就會變得相當費時費力。特別是其對於記憶體的需 求,也將是成倍的增長,以至於在某些應用中使用DOM是一件很不划算的事(比如在applet中)。這時候,一個較好的替代解決方法就是SAX。

SAX在概念上與DOM完全不同。首先,不同於DOM的文件驅動,它是事件驅動的,也就是說,它並不需要讀入整個文件,而文件的讀入過程也就是 SAX的解析過程。所謂事件驅動,是指一種基於回撥(callback)機制的程式執行方法。(如果你對Java新的代理事件模型比較清楚的話,就會很容 易理解這種機制了)

在XMLReader接受XML文件,在讀入XML文件的過程中就進行解析,也就是說讀入文件的過程和解析的過程是同時進行的,這和DOM區別很 大。解析開始之前,需要向XMLReader註冊一個ContentHandler,也就是相當於一個事件監聽器,在ContentHandler中定義 了很多方法,比如startDocument(),它定製了當在解析過程中,遇到文件開始時應該處理的事情。當XMLReader讀到合適的內容,就會拋 出相應的事件,並把這個事件的處理權代理給ContentHandler,呼叫其相應的方法進行響應

dom解析xml

<span style="font-size:18px;">import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

public class DOMParsePage {

public DOMParsePage() {
DocumentBuilderFactory domfac=DocumentBuilderFactory.newInstance();
try {
DocumentBuilder dombuilder=domfac.newDocumentBuilder();
InputStream is=new FileInputStream("C:/123.xml");
Document doc=dombuilder.parse(is);
Element root=doc.getDocumentElement();
NodeList books=root.getChildNodes(); 
if(books!=null){
for(int i=0;i<books.getLength();i++){
Node book=books.item(i);
for(Node node=book.getFirstChild();node!=null;node=node.getNextSibling())
{
if(node.getNodeType()==Node.ELEMENT_NODE){  

if(node.getNodeName().equals("title")){
String bookname=node.getFirstChild().getNodeValue(); 
System.out.println(bookname);
} 

if(node.getNodeName().equals("author")){
String author1=node.getFirstChild().getNodeValue(); 
System.out.println(author1);
}

if(node.getNodeName().equals("description")){
String addtime=node.getFirstChild().getNodeValue();
System.out.println(addtime);
}

if(node.getNodeName().equals("pubDate")){
String price=node.getFirstChild().getNodeValue();
System.out.println(price);
}   
}
}
}


}

}
catch (ParserConfigurationException e) {
e.printStackTrace();
}
catch (FileNotFoundException e) {
e.printStackTrace();
}
catch (SAXException e) {
e.printStackTrace();
}
catch (IOException e) {
e.printStackTrace();
}


}


public static void main(String[] args) {
new DOMParsePage();
}

}</span>
SAX解析XML
package simpleTest; 
import org.xml.sax.Attributes; 
import org.xml.sax.SAXException; 
import org.xml.sax.Locator; 
import org.xml.sax.ContentHandler; 
import org.xml.sax.InputSource; 
import org.xml.sax.helpers.DefaultHandler; 
import java.io.IOException; 

import javax.xml.parsers.SAXParser; 
import javax.xml.parsers.SAXParserFactory; 

class TestSAX extends DefaultHandler 
{ 
private StringBuffer buf; 

public TestSAX() 
{ 
super(); 
} 
public void setDocumentLocator(Locator locator) 
{ 
} 
public void startDocument() throws SAXException 
{ 
buf=new StringBuffer(); 
System.out.println("*******開始解析文件*******"); 
} 
public void endDocument() throws SAXException 
{ 
System.out.println("*******文件解析結束*******"); 
} 

public void startPrefixMapping( String prefix, String uri ) 
{ 
System.out.println("/n字首對映: " + prefix +" 開始!"+ " 它的URI是:" + uri); 
} 

public void endPrefixMapping( String prefix ) 
{ 
System.out.println("/n字首對映: "+prefix+" 結束!"); 
} 
public void processingInstruction( String target, String instruction ) 
throws SAXException 
{ 
} 
public void ignorableWhitespace( char[] chars, int start, int length ) throws SAXException 
{ 
} 

public void skippedEntity( String name ) throws SAXException 
{ 
} 

public void startElement(String namespaceURI,String localName,String qName,Attributes atts) 
{ 
System.out.println("*******開始解析元素*******"); 
System.out.println("元素名"+qName); 
for(int i=0;i<atts.getLength();i++) 
{ 
System.out.println("元素名"+atts.getLocalName(i)+"屬性值"+atts.getValue(i)); 
} 
} 

public void endElement(String namespaceURI,String localName,String fullName )throws SAXException 
{ 
System.out.println("******元素解析結束********"); 
} 
public void characters( char[] chars, int start, int length )throws SAXException 
{ 
//將元素內容累加到StringBuffer中 
buf.append(chars,start,length); 
} 

public static void main(String args[]) 
{ 
try{ 

SAXParserFactory sf = SAXParserFactory.newInstance(); 
SAXParser sp = sf.newSAXParser(); 
TestSAX testsax=new TestSAX(); 
sp.parse(new InputSource("D://test//simpleTest//classes//simpleTest//test.xml"),testsax); 

}catch(IOException e) 
{ 
e.printStackTrace(); 
}catch(SAXException e) 
{ 
e.printStackTrace(); 
}catch(Exception e) 
{ 
e.printStackTrace(); 
} 

} 
} 
XML檔案如下: 
<?xml version="1.0" encoding="gb2312"?> 
<row> 
<person> 
<name>王小明</name> 
<college>資訊學院</college> 
<telephone>6258113</telephone> 
<notes>男,1955年生,博士,95年調入海南大學</notes>