<一>簡介
什麼是SAX呢?以前只是聽說SAX,SAX的,但從未接觸,今天學習一下,順便做一下筆記。
SAX是Simple API for XML的縮寫,它既是一個介面也是一個包。
SAX是一個解析速度快並且佔用記憶體少的xml解析器,非常適合用於Android等行動裝置。 這個不同於DOM解析,DOM是把全部資料放入記憶體進行解析。
SAX解析XML檔案採用的是事件驅動,也就是說,它並不需要解析完整個文檔。在按內容順序解析文檔的過程中,SAX會判斷當前讀到的字元是否合法XML文法中的某部分,如果符合就會觸發事件。所謂事件,其實就是一些回調方法,這些方法定義在ContentHandler介面中。
另外一點就是:SAX在解析件的過程中得到自己需要的資訊後可以隨時終止解析,並不一定要等檔案全部解析完畢。
有優勢必定優劣勢:SAX採用的是串流方式,當遇到某個標籤的時候,它並不會記錄下以前所遇到的標籤,也就是說,在處理某個標籤的時候,比如在startElement方法中,所能夠得到的資訊就是標籤的名字和屬性,至於標籤內部的嵌套結構,上層標籤、下層標籤以及其兄弟節點的名稱等等與其結構相關的資訊都是不得而知的。實際上就是把XML檔案的結構資訊丟掉了,如果需要得到這些資訊的話,只能你自己在程式裡進行處理了。所以相對DOM而言,SAX處理XML文檔沒有DOM方便,SAX處理的過程相對DOM而言也比較複雜。
<二>ContentHandler介面常用的方法
startDocument()
當遇到文檔的開頭的時候,調用這個方法,可以在其中做一些預先處理的工作。
endDocument()
和上面的方法相對應,當文檔結束的時候,調用這個方法,可以在其中做一些善後的工作。
startElement(String namespaceURI, String localName, String qName, Attributes atts)
當讀到一個開始標籤的時候,會觸發這個方法。namespaceURI就是命名空間,localName是不帶命名空間首碼的標籤名,qName是帶命名空間首碼的標籤 名。通過atts可以得到所有的屬性名稱和相應的值。要注意的是SAX中一個重要的特點就是它的串流,當遇到一個標籤的時候,它並不會紀錄下以前所碰
到的標籤,也就是說,在startElement()方法中,所有你所知道的資訊,就是標籤的名字和屬性,至於標籤的嵌套結構,上層標籤的名字,是否有子元屬 等等其它與結構相關的資訊,都是不得而知的,都需要你的程式來完成。這使得SAX在編程處理上沒有DOM來得那麼方便。
endElement(String uri, String localName, String name)
這個方法和上面的方法相對應,在遇到結束標籤的時候,調用這個方法。
characters(char[] ch, int start, int length)
這個方法用來處理在XML檔案中讀到的內容。例如:<name>xiaosi</name> 主要目的是擷取name標籤中的值。
第一個參數用於存放檔案的內容,後面兩個參數是讀到的字串在這個數組中的起始位置和長度,使用new
String(ch,start,length)就可以擷取內容。
<?xml version="1.0"?> ---------->startDocument()
<student> ---------->startElement
<name> ---------->startElement
xiasoi ---------->characters
</name> ---------->endElement
<id>
---------->startElement
090105 ---------->characters
</id> ---------->endElement
</student> --------->endElement
文檔結束 --------->startDocument()
<三>解析步驟
使用SAX解析XML檔案一般有以下五個步驟:
1、建立一個SAXParserFactory對象(通過類名很容易得知它利用Factory 方法模式實現的);
2、調用SAXParserFactory中的newSAXParser方法建立一個SAXParser對象;
3、然後在調用SAXParser中的getXMLReader方法擷取一個XMLReader對象;
4、在XMLReader中註冊事件處理介面,一般有ContentHandler、ErrorHandler、DTDHandler、EntityHandler四種;
5、調用XMLReader中的parse方法解析指定的XML字串對象;
具體實現:
注意:因為ContentHandler是一個介面,在使用的時候有些不方便,需要全部實現所有的方法,但是有些方法我們會用不到。因此,SAX還為其制定了一個Helper類:DefaultHandler,它實現了這個介面,但是其所有的方法體都為空白,在實現的時候,你只需要繼承這個類,然後重載相應的方法即可
package xiaosi.sax;</p><p>import java.io.IOException;<br />import java.io.StringReader;</p><p>import javax.xml.parsers.ParserConfigurationException;<br />import javax.xml.parsers.SAXParserFactory;</p><p>import org.apache.http.HttpResponse;<br />import org.apache.http.client.HttpClient;<br />import org.apache.http.client.methods.HttpGet;<br />import org.apache.http.impl.client.DefaultHttpClient;<br />import org.apache.http.protocol.HTTP;<br />import org.apache.http.util.EntityUtils;<br />import org.xml.sax.InputSource;<br />import org.xml.sax.SAXException;<br />import org.xml.sax.XMLReader;</p><p>import android.app.Activity;<br />import android.os.Bundle;<br />import android.view.View;<br />import android.view.View.OnClickListener;<br />import android.widget.Button;</p><p>public class XMLSAXActivity extends Activity<br />{<br />private Buttonbutton= null;<br />private StringxmlContent= "";</p><p>@Override<br />public void onCreate(Bundle savedInstanceState)<br />{<br />super.onCreate(savedInstanceState);<br />setContentView(R.layout.main);<br />button = (Button) findViewById(R.id.button);<br />button.setOnClickListener(new OnClickListener() {<br />@Override<br />public void onClick(View v)<br />{<br />try<br />{<br />getWeatherArray("beijing");<br />SAXParserFactory saxFactory = SAXParserFactory.newInstance();<br />XMLReader xmlReader = saxFactory.newSAXParser().getXMLReader();<br />xmlReader.setContentHandler(new MyContentHandler());<br />String xml= "<student><name>xiaosi</name><id>090105</id></student>";<br />xmlReader.parse(new InputSource(new StringReader(xml)));<br />}<br />catch (SAXException e)<br />{<br />e.printStackTrace();<br />}<br />catch (ParserConfigurationException e)<br />{<br />e.printStackTrace();<br />}<br />catch (IOException e)<br />{<br />e.printStackTrace();<br />}<br />catch (Exception e)<br />{<br />e.printStackTrace();<br />}<br />}<br />});<br />}<br />}<br />
MyContentHandler:
package xiaosi.sax;</p><p>import org.xml.sax.Attributes;<br />import org.xml.sax.SAXException;<br />import org.xml.sax.helpers.DefaultHandler;</p><p>import android.util.Log;</p><p>public class MyContentHandler extends DefaultHandler<br />{<br />Stringtag= "XIAOSI";</p><p>@Override<br />public void startDocument() throws SAXException<br />{<br />Log.i(tag, "startDocument");<br />}</p><p>@Override<br />public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException<br />{<br />Log.i(tag, "startElement");<br />}</p><p>@Override<br />public void characters(char[] ch, int start, int length) throws SAXException<br />{<br />Log.i(tag, "characters");<br />}</p><p>@Override<br />public void endDocument() throws SAXException<br />{<br />Log.i(tag, "endDocument");<br />}</p><p>@Override<br />public void endElement(String uri, String localName, String qName) throws SAXException<br />{<br />Log.i(tag, "endElement");<br />}<br />}<br />