首頁  >  文章  >  後端開發  >  XML SAX解析詳解

XML SAX解析詳解

PHPz
PHPz原創
2017-04-04 10:57:221769瀏覽



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就是實作了上面的四個事件處理器接口,然後提供了每個抽象方法的預設實作。)


##1,ContentHandler 介面:接收文檔邏輯內容的通知的處理器介面。

Java程式碼 收藏程式碼

'import org.xml.sax.Attributes;

import org.xml.sax.ContentHandler;

import org. xml.sax.Locator;

import org.xml.sax.SAXException;


##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 範圍的對應。

*/

@Override

public void endPrefixMapping(String prefix) throws SAXException {

System.out.println(this.toBlankString(-- this.frontBlankCount)+

">>> end prefix_mapping : "+prefix);

}


/*

* 接收元素內容中可忽略的空白的通知。

* 參數意義如下:

*     ch : 來自XML 文件的字元

*     start : 陣列中的開始位置

*     length : 從陣列中的開始位置

*     length : 從陣列中的開始位置

*     length : 從陣列中讀取的字元的數目

*/

@Override

public void ignorableWhitespace(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)+">>> 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()+")");

#}

##/*

* 接收跳過的實體的通知。

* 參數意義如下:

*     name : 所跳過的實體的名稱。如果它是參數實體,則名稱將以 '%' 開頭,###

*            如果它是外部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 ");

#}


##/*

*接收元素開始的通知。

* 參數意義如下:

*    uri :元素的命名空間

*    localName :元素的本機名稱(不含前綴)

*    qName :元素的限定名(帶前綴)

*    atts :元素的屬性集合

*/

@Override

public void startElement(String uri , String localName, String qName,

Attributes atts) throws SAXException {

System.out.println(this.toBlankString(this.frontBlankCount++)+

#">> ;> start element : "+qName+"("+uri+")");

#}


/*

*開始前綴URI 名稱空間範圍映射。

* 此事件的資訊對於常規的命名空間處理並非必要:

* 當http://xml.org/sax/features/namespaces 功能為true(預設)時,

* SAX XML 讀取器將自動替換元素和屬性名稱的前綴。

* 參數意義如下:

*    prefix :前綴

*    uri :命名空間

*/

@Override

public void startPrefixMapping(String prefix,String uri)

throws SAXException {

System.out.println(this.toBlankString(this.frontBlankCount++)+








# ">>> start prefix_mapping : xmlns:"+prefix+" = "

+"\\\\\\\\\\\\\\\\\\\\\\\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\""+uri+"\\\\\\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ \\\\\\\\\"");

}


#private String toBlankString(int count ){

StringBuffer buffer = new StringBuffer();

for(int i = 0;i

buffer.append("    ");

# return buffer.toString();

}

#}'







##################################' ######2,DTDHandler 介面:接收與DTD 相關的事件的通知的處理器介面。 ######import org.xml.sax.SAXException;################public class MyDTDHandler implements DTDHandler {################ #/*######* 接收註解宣告事件的通知。的公共標識符,如果未提供,則為null。 ######*     systemId - 註釋的系統標識符,如果未提供,則為 null。 ######*/######@Override######public void notationDecl(String name, String publicId, String systemId)######throws SAXException {####### System.out.println(">>> notation declare : (name = "+name######+",systemId = "+publicId######+",publicId = "+systemId+ ")");######}###############/*######* 接收未解析的實體宣告事件的通知。 ######* 參數意義如下:######*     name - 未解析的實體的名稱。 ######*     publicId - 實體的公共識別符,如果未提供,則為 null。 ######*     systemId - 實體的系統識別碼。 ######*     notationName - 相關註解的名稱。 ######*/######@Override######public void unparsedEntityDecl(String name,######String publicId,#######String systemId,### ###String notationName) throws SAXException {######System.out.println(">>> unparsed entity declare : (name = "+name#######+",systemId = " +publicId######+",publicId = "+systemId######+",notationName = "+notationName+")");######}######### #######}'#########################3,EntityResolver 介面:是用來解析實體的基本介面。 ######Java程式碼 收藏程式碼######'import java.io.IOException;###############import org.xml.sax.EntityResolver;## ####import org.xml.sax.InputSource;######import org.xml.sax.SAXException;###############public class MyEntityResolver implements EntityResolver {# ##############/*######* 允許應用程式解析外部實體。 ######* 解析器會在開啟任何外部實體(頂層文件實體除外)之前呼叫此方法######* 參數意義如下:######*     publicId : 被引用的外部實體的公共標識符,如果未提供,則為null。 ######*     systemId : 被引用的外部實體的系統識別碼。 ###

* 傳回:

*     一個描述新輸入來源的 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());

##}


#/*

* 接收不可恢復的錯誤的通知。

*/

@Override

public void warning(SAXParseException e) throws SAXException {

System.err.println("Warning ("+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")));

}

#}'








#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中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn