Android之解析XML总结(SAX、Pull、Dom三种方式)
? ? ? ? 常見的解析xml的方式有一下三種:SAX、Pull、Dom解析方式。最近做了一個android版的CSDN閱讀器,用到了其中的兩種(sax,pull),今天對android解析xml的這三種方式進行一次總結。
? ? ? ? ?今天解析的xml示例(channels.xml)如下:
<?xml version="1.0" encoding="utf-8"?> <channel> <item id="0" url="http://www.baidu.com">百度</item> <item id="1" url="http://www.qq.com">騰訊</item> <item id="2" url="http://www.sina.com.cn">新浪</item> <item id="3" url="http://www.taobao.com">淘寶</item> </channel>一、使用sax方式解析
?基礎知識:
? ? ?這種方式解析是一種基于事件驅動的api,有兩個部分,解析器和事件處理器,解析器就是XMLReader接口,負責讀取XML文檔,和向事件處理器發送事件(也是事件源),事件處理器ContentHandler接口,負責對發送的事件響應和進行XML文檔處理。
? ? ?下面是ContentHandler接口的常用方法
? ? ?public abstract void characters (char[] ch, int start, int length)
? ? ? 這個方法來接收字符塊通知,解析器通過這個方法來報告字符數據塊,解析器為了提高解析效率把讀到的所有字符串放到一個字符數組(ch)中,作為參數傳遞給character的方法中,如果想獲取本次事件中讀取到的字符數據,需要使用start和length屬性。
? ??public abstract void startDocument () 接收文檔開始的通知
? ???public abstract void endDocument () 接收文檔結束的通知
? ??public abstract void startElement (String uri, String localName, String qName, Attributes atts) 接收文檔開始的標簽
? ??public abstract void endElement (String uri, String localName, String qName) 接收文檔結束的標簽
? ? 在一般使用中為了簡化開發,在org.xml.sax.helpers提供了一個DefaultHandler類,它實現了ContentHandler的方法,我們只想繼承DefaultHandler方法即可。
? ?另外SAX解析器提供了一個工廠類:SAXParserFactory,SAX的解析類為SAXParser 可以調用它的parser方法進行解析。
? ?看了些基礎以后開始上代碼吧(核心代碼,下載代碼在附件)
public class SAXPraserHelper extends DefaultHandler {final int ITEM = 0x0005;List<channel> list;channel chann;int currentState = 0;public List<channel> getList() {return list;}/** 接口字符塊通知 */@Overridepublic void characters(char[] ch, int start, int length)throws SAXException {// TODO Auto-generated method stub // super.characters(ch, start, length);String theString = String.valueOf(ch, start, length);if (currentState != 0) {chann.setName(theString);currentState = 0;}return;}/** 接收文檔結束通知 */@Overridepublic void endDocument() throws SAXException {// TODO Auto-generated method stubsuper.endDocument();}/** 接收標簽結束通知 */@Overridepublic void endElement(String uri, String localName, String qName)throws SAXException {// TODO Auto-generated method stubif (localName.equals("item"))list.add(chann);}/** 文檔開始通知 */@Overridepublic void startDocument() throws SAXException {// TODO Auto-generated method stublist = new ArrayList<channel>();}/** 標簽開始通知 */@Overridepublic void startElement(String uri, String localName, String qName,Attributes attributes) throws SAXException {// TODO Auto-generated method stubchann = new channel();if (localName.equals("item")) {for (int i = 0; i < attributes.getLength(); i++) {if (attributes.getLocalName(i).equals("id")) {chann.setId(attributes.getValue(i));} else if (attributes.getLocalName(i).equals("url")) {chann.setUrl(attributes.getValue(i));}}currentState = ITEM;return;}currentState = 0;return;} }private List<channel> getChannelList() throws ParserConfigurationException, SAXException, IOException{//實例化一個SAXParserFactory對象SAXParserFactory factory=SAXParserFactory.newInstance();SAXParser parser;//實例化SAXParser對象,創建XMLReader對象,解析器parser=factory.newSAXParser();XMLReader xmlReader=parser.getXMLReader();//實例化handler,事件處理器SAXPraserHelper helperHandler=new SAXPraserHelper();//解析器注冊事件xmlReader.setContentHandler(helperHandler);//讀取文件流InputStream stream=getResources().openRawResource(R.raw.channels);InputSource is=new InputSource(stream);//解析文件xmlReader.parse(is);return helperHandler.getList();}
從第二部分代碼,可以看出使用SAX解析XML的步驟:
1、實例化一個工廠SAXParserFactory
2、實例化SAXPraser對象,創建XMLReader 解析器
3、實例化handler,處理器
4、解析器注冊一個事件
4、讀取文件流
5、解析文件
二、使用pull方式解析
? 在android系統中,很多資源文件中,很多都是xml格式,在android系統中解析這些xml的方式,是使用pul解析器進行解析的,它和sax解析一樣(個人感覺要比sax簡單點),也是采用事件驅動進行解析的,當pull解析器,開始解析之后,我們可以調用它的next()方法,來獲取下一個解析事件(就是開始文檔,結束文檔,開始標簽,結束標簽),當處于某個元素時可以調用XmlPullParser的getAttributte()方法來獲取屬性的值,也可調用它的nextText()獲取本節點的值。
其實以上描述,就是對整個解析步驟的一個描述,看看代碼吧
private List<Map<String, String>> getData() {List<Map<String, String>> list = new ArrayList<Map<String, String>>();XmlResourceParser xrp = getResources().getXml(R.xml.channels);try {// 直到文檔的結尾處while (xrp.getEventType() != XmlResourceParser.END_DOCUMENT) {// 如果遇到了開始標簽if (xrp.getEventType() == XmlResourceParser.START_TAG) {String tagName = xrp.getName();// 獲取標簽的名字if (tagName.equals("item")) {Map<String, String> map = new HashMap<String, String>();String id = xrp.getAttributeValue(null, "id");// 通過屬性名來獲取屬性值map.put("id", id);String url = xrp.getAttributeValue(1);// 通過屬性索引來獲取屬性值map.put("url", url);map.put("name", xrp.nextText());list.add(map);}}xrp.next();// 獲取解析下一個事件}} catch (XmlPullParserException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}return list;}三、使用Dom方式解析
基礎知識:
? ? ?最后來看看Dom解析方式,這種方式解析自己之前也沒有用過(在j2ee開發中比較常見,沒有做過這方面的東西),在Dom解析的過程中,是先把dom全部文件讀入到內存中,然后使用dom的api遍歷所有數據,檢索想要的數據,這種方式顯然是一種比較消耗內存的方式,對于像手機這樣的移動設備來講,內存是非常有限的,所以對于比較大的XML文件,不推薦使用這種方式,但是Dom也有它的優點,它比較直觀,在一些方面比SAX方式比較簡單。在xml文檔比較小的情況下也可以考慮使用dom方式。
Dom方式解析的核心代碼如下:
public static List<channel> getChannelList(InputStream stream){List<channel> list=new ArrayList<channel>();//得到 DocumentBuilderFactory 對象, 由該對象可以得到 DocumentBuilder 對象DocumentBuilderFactory factory=DocumentBuilderFactory.newInstance();try {//得到DocumentBuilder對象DocumentBuilder builder=factory.newDocumentBuilder();//得到代表整個xml的Document對象Document document=builder.parse(stream);//得到 "根節點" Element root=document.getDocumentElement();//獲取根節點的所有items的節點NodeList items=root.getElementsByTagName("item"); //遍歷所有節點for(int i=0;i<items.getLength();i++){channel chann=new channel();Element item=(Element)items.item(i);chann.setId(item.getAttribute("id"));chann.setUrl(item.getAttribute("url"));chann.setName(item.getFirstChild().getNodeValue());list.add(chann);}} catch (ParserConfigurationException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (SAXException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}return list;}總結一下Dom解析的步驟(和sax類似)
1、調用 DocumentBuilderFactory.newInstance() 方法得到 DOM 解析器工廠類實例。
2、調用解析器工廠實例類的?newDocumentBuilder() 方法得到 DOM 解析器對象
3、調用 DOM 解析器對象的 parse()?方法解析 XML 文檔得到代表整個文檔的 Document 對象。
四、總結
? ? ? ?除以上三種外還有很多解析xml的方法,比如DOM4J、JDOM等等。但其基本的解析方式包含兩種,一種是事件驅動的(代表SAX),另一種方式是基于文檔結構(代表DOM)。其他的只不過語法不一樣而已。
總結
以上是生活随笔為你收集整理的Android之解析XML总结(SAX、Pull、Dom三种方式)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Android之内存溢出(Out Of
- 下一篇: Android之基于BaseAdapte