DOM和SAX的最終功能是可以讓我們利用java JavaScript等語言來取得xml檔案中的節點及文字、屬性等資訊。
本文引自其他博客,內容易懂,為了節省時間,直接摘抄過來了。 JAVA 解析 XML 通常有兩種方式,DOM 和 SAX。 DOM 雖然是W3C 的標準,提供了標準的解析方式,但它的解析效率一直不盡如人意,因為使用DOM解析XML時,解析器讀入整個文檔並構建一個駐留內存的樹結構(節點樹),然後您的程式碼才可以使用DOM 的標準介面來操作這個樹結構。但大部分情況下我們只對文檔的部分內容感興趣,根本就不用先解析整個文檔,並且從節點樹的根節點來索引一些我們需要的資料也是非常耗時的。
SAX是一種XML解析的替代方法。相較於文檔物件模型DOM,SAX 是讀取和操作 XML 資料的更快速、更輕的方
法。 SAX 允許您在讀取文件時處理它,而不必等待整個文件儲存後才採取操作。它不涉及 DOM 所必需的開銷和概念跳躍。 SAX API是一個基於事件的API ,適用於處理資料流,即隨著資料的流動而依序處理資料。 SAX API
在其解析您的文件時發生一定事件的時候會通知您。當您對其回應時,您不作保存的資料將會 被拋棄。
下面是SAX解析XML的範例(有點長,因為詳細註解了SAX事件處理的所有方法),SAX API中主要有四種處理事件的接口,它們分別是ContentHandler,DTDHandler, EntityResolver 和ErrorHandler 。下面的例子可能有點冗長,實際上只要繼承DefaultHandler 類別 ,再覆蓋一部分 處理事件的方法 同樣可以達到這個範例的效果,但為了縱觀全局,還是看看SAX API裡面所有主要的事件解析方法吧。 ( 實際上DefaultHandler就是實作了上面的四個事件處理器接口,然後提供了每個抽象方法的預設實作。)
##class MyContentHandler implements ContentHandler{
StringBuffer jsonStringBuffer ;
int frontBlankCount = 0;
public MyContentHandler(){
jsonStringBuffer = new StringBuffer();
#}
/*
* 接收字元資料的通知。
* 在DOM中ch[begin:end] 相當於Text節點的節點值(nodeValue)
*/
@Override
public void characters(char[] ch, int begin, int length) throws SAXException {
StringBuffer buffer = new StringBuffer();
for(int i = begin ; i < begin+length ; i++){
switch(ch[i]){
case '\\\\\\\\\\\\\\\\\\\\\\\\\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ \\\':buffer.append("\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ \\\\\\\\\\\\\\\\");break;
case '\\\\\\\\\\\\\\\\\\\\\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\r':buffer.append( "\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\r");break;
case '\\\\\\\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ \\\\\\\n':buffer.append("\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\n");break;
case '\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ \\\\\\\\\\\\\\\\\\\\t':buffer.append("\\\\\\\\\\\\\\\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ \\\\\\\t");break;
case '\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\」':buffer.append("\\\\\\\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\」");break;
default : buffer .append(ch[i]);
}
}
System.out.println(this.toBlankString(this.frontBlankCount)+
# ">>> characters("+length+"): "+buffer.toString());
}
################################ #####/*######* 接收文件的結尾的通知。 ######*/######@Override######public void endDocument() throws SAXException {######System.out.println(this.toBlankString(--this. frontBlankCount)+###">>> end document");
}
/*
* 接收文件的結尾的通知。
* 參數意義如下:
* uri :元素的命名空間
* localName :元素的本機名稱(不含前綴)
* qName :元素的限定名(帶前綴)
*
*/
#@Override
public void endElement(String uri,String localName,String qName )
throws SAXException {
System.out.println(this.toBlankString(--this.frontBlankCount)+
">>> end element : " +qName+"("+uri+")");
}
#/*
##* 結束前綴URI 範圍的對應。 */@Overridepublic void endPrefixMapping(String prefix) throws SAXException {System.out.println(this.toBlankString(-- this.frontBlankCount)+">>> end prefix_mapping : "+prefix);}}}System.out.println(this.toBlankString(this.frontBlankCount)+">>> ignorable whitespace("+length+"): "+ buffer.toString());
}
##* 接收處理指令的通知。
* 參數意義如下:
* target : 處理指令目標
* data : 處理指令數據,若未提供,則為 null。
*/
@Override
public void processingInstruction(String target,String data)
throws SAXException {
System.out .println(this.toBlankString(this.frontBlankCount)+">>> process instruction : (target = \\\\\\\\\\\\\\\\\\\\\\\\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\""
+target+" \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ \\\\\\\\\\\\\\",data = \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\""+data+"\\\\\\\\\\\\\\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ \")");
}
/*
* 接收用來尋找SAX 文件事件起源的物件。
* 參數意義如下:
* locator : 可以傳回任何SAX 文件事件位置的物件
*/
@Override
public void setDocumentLocator(Locator locator) {
System.out.println(this.toBlankString(this.frontBlankCount)+
">>> set document_locator : (lineNumber = " +locator.getLineNumber()
+",columnNumber = "+locator.getColumnNumber()
+",systemId = "+locator.getSystemId()
#+" ,publicId = "+locator.getPublicId()+")");
#}
* 如果它是外部DTD 子集,則會是字串"[dtd]"
*/
@Override
public void skippedEntity(String name ) throws SAXException {
System.out.println(this.toBlankString(this.frontBlankCount)+
">>> skipped_entity : "+name);
#}
/*
* 接收文件的開始的通知。
*/
@Override
public void startDocument() throws SAXException {
System.out.println(this.toBlankString(this.frontBlankCount++) +
">>> start document ");
#}
# ">>> start prefix_mapping : xmlns:"+prefix+" = "
+"\\\\\\\\\\\\\\\\\\\\\\\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\""+uri+"\\\\\\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ \\\\\\\\\"");
}#}'
* 傳回:
* 一個描述新輸入來源的 InputSource 對象,或傳回 null,
* 以請求解析器開啟到系統識別碼的常規 URI 連線。
*/
@Override
public InputSource resolveEntity(String publicId, String systemId)
throws SAXException, IOException {
return null;
}
}
#4,ErrorHandler介面:是錯誤處理程序的基本接口。
Java程式碼 收藏程式碼
import org.xml.sax.ErrorHandler;
import org.xml.sax.SAXException;
import org.xml .sax.SAXParseException;
public class MyErrorHandler implements ErrorHandler {
/*
*接收可恢復的錯誤的通知
*/
@Override
public void error(SAXParseException e) throws SAXException {
System.err.println ("Error ("+e.getLineNumber()+","
+e.getColumnNumber()+") : "+e.getMessage());
}
#/*
* 接收不可恢復的錯誤的通知。
*/
@Override
public void fatalError(SAXParseException e) throws SAXException {
System.err.println("FatalError ("+e .getLineNumber()+","
+e.getColumnNumber()+") : "+e.getMessage());
##}##}
#}
Test 類別的主方法列印解析books.xml時的事件資訊。
Java程式碼 收藏程式碼
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import org.xml.sax.ContentHandler;
import org.xml.sax.DTDHandler;
import org.xml.sax .EntityResolver;
import org.xml.sax.ErrorHandler;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;
import org.xml.sax.helpers.XMLReaderFactory;
public class Test {
public static void main(String[] args) throws SAXException,
FileNotFoundException, IOException {
#//建立處理文件內容相關事件的處理器
ContentHandler contentHandler = new MyContentHandler();
//建立處理錯誤事件處理器
ErrorHandler errorHandler = new MyErrorHandler();
//建立處理DTD相關事件的處理器
DTDHandler dtdHandler = new MyDTDHandler();
#//建立實體解析器
EntityResolver entityResolver = new MyEntityResolver();
//建立一個XML解析器(透過SAX方式讀取解析XML)
XMLReader reader = XMLReaderFactory.createXMLReader();
##/** 設定解析器的相關特性* http://xml.org/sax/features/validation = true表示開啟驗證特性* http://xml.org/sax/features/namespaces = true 表示開啟命名空間特性*/reader.setFeature(" http://xml.org/sax/features/validation",true);reader.setFeature("http://xml.org/sax/features/namespaces",true);//設定XML解析器的處理文件內容相關事件的處理器reader.setContentHandler(contentHandler);//設定XML解析器的處理錯誤事件處理器reader.setErrorHandler(errorHandler);//設定XML解析器的處理DTD相關事件的處理器reader.setDTDHandler(dtdHandler); #//設定XML解析器的實體解析器reader.setEntityResolver(entityResolver);//解析books.xml文件reader.parse(new InputSource( new FileReader("books.xml")));}
#}'
Xml程式碼 收藏程式碼
#Thinking in JAVA
#Core JAVA2
Core JAVA2 ##############C++ primer######################################################################################## ####控制台輸出如下:###############>>> set document_locator : (lineNumber = 1,columnNumber = 1,systemId = null,publicId = null) ######>>> start document######Error (2,7) : Document is invalid: no grammar found.#######Error (2,7) : Document root element "books", must match DOCTYPE root "null".######>>> start prefix_mapping : xmlns: = "http://test.org/books"######> >> start element : books(http://test.org/books)#######>>> characters(2): \\\\\\\\\\\\\\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ n\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ \\\\\\\\\\\\\\\t###>>>字元(2): \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ \\\\\\\\\\\\\\\\\n\\\\\\\\\\\\\\\\\\\\\\\\\\n\\\\ \\\\\\\\\\\\\\\\\\\\\\\\\ \\\\\\\\\\\\\\\\\\\\\\\\\ \\\\\t
>>>>起始元素:book(http://test.org/books)
>>字元(3): \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ \\\\\\\\\\\\\\\\\n\\\\\\\\\\\\\\\\\\\\\\\\\\n\\\\ \\\\\\\\\\\\\\\\\\\\\\\\\ \\\\\\\\\\\\\\\\\\\\\\\\\ \\\\\\\t\\\\\\\\\\\\\\\ \\\\\\\\\\\\\\\\\\\\\\\\\\\ \\\\\\\\\\\\\\\\\\t
>>>>起始元素:名稱(http://test.org/books)
>>字符(16):JAVA思維
>>結束元素:名稱(http://test.org/books)
>>字元(2): \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ \\\\\\\\\\\\\\\\\n\\\\\\\\\\\\\\\\\\\\\\\\\\n\\\\ \\\\\\\\\\\\\\\\\\\\\\\\\ \\\\\\\\\\\\\\\\\\\\\\\\\ \\\\\\\t
>>>>結束元素:book(http://test.org/books)
>>字元(2): \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ \\\\\\\\\\\\\\\\\n\\\\\\\\\\\\\\\\\\\\\\\\\\n\\\\ \\\\\\\\\\\\\\\\\\\\\\\\\ \\\\\\\\\\\\\\\\\\\\\\\\\ \\\\\\\t
>>>>起始元素:book(http://test.org/books)
>>字元(3): \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ \\\\\\\\\\\\\\\\\n\\\\\\\\\\\\\\\\\\\\\\\\\\n\\\\ \\\\\\\\\\\\\\\\\\\\\\\\\ \\\\\\\\\\\\\\\\\\\\\\\\\ \\\\\\\t\\\\\\\\\\\\\\\ \\\\\\\\\\\\\\\\\\\\\\\\\\\ \\\\\\\\\\\\\\\\\\t
>>>>起始元素:名稱(http://test.org/books)
>>字元(10):核心JAVA2
>>結束元素:名稱(http://test.org/books)
>>字元(2): \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ \\\\\\\\\\\\\\\\\n\\\\\\\\\\\\\\\\\\\\\\\\\\n\\\\ \\\\\\\\\\\\\\\\\\\\\\\\\ \\\\\\\\\\\\\\\\\\\\\\\\\ \\\\\\\t
>>>>結束元素:book(http://test.org/books)
>>字元(2): \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ \\\\\\\\\\\\\\\\\n\\\\\\\\\\\\\\\\\\\\\\\\\\n\\\\ \\\\\\\\\\\\\\\\\\\\\\\\\ \\\\\\\\\\\\\\\\\\\\\\\\\ \\\\\\\t
>>>>起始元素:book(http://test.org/books)
>>字元(3): \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ \\\\\\\\\\\\\\\\\n\\\\\\\\\\\\\\\\\\\\\\\\\\n\\\\ \\\\\\\\\\\\\\\\\\\\\\\\\ \\\\\\\\\\\\\\\\\\\\\\\\\ \\\\\\\t\\\\\\\\\\\\\\\ \\\\\\\\\\\\\\\\\\\\\\\\\\\ \\\\\\\\\\\\\\\\\\t
>>>>起始元素:名稱(http://test.org/books)
>>字元(10):C++ 入門
>>>>結束元素:名稱(http://test.org/books)
>>字元(2): \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ \\\\\\\\\\\\\\\\\n\\\\\\\\\\\\\\\\\\\\\\\\\\n\\\\ \\\\\\\\\\\\\\\\\\\\\\\\\ \\\\\\\\\\\\\\\\\\\\\\\\\ \\\\\\\t
>>>>結束元素:book(http://test.org/books)
>>字元(1): \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ \\\\\\\\\\\\\\\\\n
>>>>結束元素:書籍(http://test.org/books)
>>結束前綴映射:
>>結束文檔
以上是XML SAX解析詳解的詳細內容。更多資訊請關注PHP中文網其他相關文章!