最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

詳解android使用SAX解析XML文件

 更新時(shí)間:2016年11月10日 10:51:22   作者:HuaDeFei  
本篇文章主要是介紹了android使用SAX解析XML文件,解析XML的方式有很多種,本篇主要介紹使用sax來解析,需要的可以了解一下。

解析XML的方式有很多種,大家比較熟悉的可能就是DOM解析。

DOM(文件對象模型)解析:解析器讀入整個(gè)文檔,然后構(gòu)建一個(gè)駐留內(nèi)存的樹結(jié)構(gòu),然后代碼就可以根據(jù)DOM接口來操作這個(gè)樹結(jié)構(gòu)了。

優(yōu)點(diǎn):整個(gè)文檔讀入內(nèi)存,方便操作:支持修改、刪除和重現(xiàn)排列等多種功能。

缺點(diǎn):將整個(gè)文檔讀入內(nèi)存中,保留了過多的不需要的節(jié)點(diǎn),浪費(fèi)內(nèi)存和空間。

使用場合:一旦讀入文檔,還需要多次對文檔進(jìn)行操作,并且在硬件資源充足的情況下(內(nèi)存,CPU)。

為了解決DOM解析存在的問題,就出現(xiàn)了SAX解析。其特點(diǎn)為:

優(yōu)點(diǎn):不用實(shí)現(xiàn)調(diào)入整個(gè)文檔,占用資源少。尤其在嵌入式環(huán)境中,如android,極力推薦使用SAX解析。

缺點(diǎn):不像DOM解析一樣將文檔長期駐留在內(nèi)存中,數(shù)據(jù)不是持久的。如果事件過后沒有保存數(shù)據(jù),數(shù)據(jù)就會丟失。

使用場合:機(jī)器有性能限制。

SAX解析XML文檔采用事件驅(qū)動模式。什么是事件驅(qū)動模式?它將XML文檔轉(zhuǎn)換成一系列的事件,由單獨(dú)的事件處理器來決定如何處理。

基于事件驅(qū)動的處理模式主要是基于事件源和事件處理器(或者叫監(jiān)聽器)來工作的。一個(gè)可以產(chǎn)生事件的對象叫做事件源,而一個(gè)可以針對事件做出響應(yīng)的對象就被叫做事件處理器。

在SAX接口中,事件源是org.xml.sax包中的XMLReader,他通過parse()方法開始解析XML文檔,并根據(jù)文檔內(nèi)容產(chǎn)生事件。而事件處理器則是org.xml.sax包中的ContentHandler、DTDHandler、ErrorHandler,以及EntityResolver這四個(gè)接口。他們分別處理事件源在解析過程中產(chǎn)生不同類的事件(其中DTDHandler為解析文檔DTD時(shí)所用)。詳細(xì)介紹如下表:

在上述四個(gè)接口中,最重要的就是ContentHandler這個(gè)接口,下面是對這個(gè)接口方法的說明:

//設(shè)置一個(gè)可以定位文檔內(nèi)容事件發(fā)生位置的定位器對象

public void setDocumentLocator(Locator locator)

//用于處理文檔解析開始事件

public void startDocument()throws SAXException

//處理元素開始事件,從參數(shù)中可以獲得元素所在名稱空間的uri,元素名稱,屬性類表等信息

public void startElement(String namespacesURI , String localName , String qName , Attributes atts) throws SAXException

//處理元素結(jié)束事件,從參數(shù)中可以獲得元素所在名稱空間的uri,元素名稱等信息

public void endElement(String namespacesURI , String localName , String qName) throws SAXException

//處理元素的字符內(nèi)容,從參數(shù)中可以獲得內(nèi)容

public void characters(char[] ch , int start , int length) throws SAXException

這里再介紹下XMLReader中的方法。

//注冊處理XML文檔解析事件ContentHandler
public void setContentHandler(ContentHandler handler)

//開始解析一個(gè)XML文檔
public void parse(InputSorce input) throws SAXException

SAX實(shí)現(xiàn)實(shí)體解析的步驟:

在android中使用SAX是有跡可循的,完全可以按照下面的方法就可以輕松找到xml里的tag,然后得到想要的內(nèi)容。具體實(shí)現(xiàn)步驟如下:

(一)第一步:新建一個(gè)工廠類SAXParserFactory,代碼如下:

SAXParserFactory factory = SAXParserFactory.newInstance();

(二)第二步:讓工廠類產(chǎn)生一個(gè)SAX的解析類SAXParser,代碼如下:

SAXParser parser = factory.newSAXParser();

(三)第三步:從SAXPsrser中得到一個(gè)XMLReader實(shí)例,代碼如下:

XMLReader reader = parser.getXMLReader();

(四)第四步:把自己寫的handler注冊到XMLReader中,一般最重要的就是ContentHandler,代碼如下:

RSSHandler handler = new RSSHandler();
reader.setContentHandler(handler);

(五)第五步:將一個(gè)xml文檔或者資源變成一個(gè)java可以處理的InputStream流后,解析正式開始,代碼如下:

parser.parse(is);

上面幾個(gè)步驟中,最重要、最關(guān)鍵的就是第四步,handler的實(shí)現(xiàn)。

下面通過一個(gè)RSS解析的例子說明handler的實(shí)現(xiàn):

我們先是自己見一個(gè)rss的xml文檔,實(shí)現(xiàn)本地解析,新建的rss文檔如下:

<?xml version="1.0" encoding="UTF-8"?>
  <channel>
    <title>RSS 解析練習(xí)</title>
    <description>hehehaha</description>
    <link>http://www.cnblogs.com/felix-hua/</link>
    <language>zh-cn</language>


    <item>
      <title><![CDATA[頭條]]></title>
      <link>http://mc.cz001.com.cn/images/menu/23_active.png</link>
      <category>0</category>
      <description>描述詳細(xì)信息的</description>
      <pubDate>2012-01-09</pubDate>
    </item>
    
    <item>
      <title><![CDATA[新聞]]></title>
      <link>http://mc.cz001.com.cn/images/menu/23_active.png</link>
      <category>0</category>
      <description>描述詳細(xì)信息的</description>
      <pubDate>2012-01-09</pubDate>
    </item>
    
    <item>
      <title><![CDATA[首頁]]></title>
      <link>http://mc.cz001.com.cn/images/menu/23_active.png</link>
      <category>0</category>
      <description>描述詳細(xì)信息的</description>
      <pubDate>2012-01-09</pubDate>
    </item>
    
    <item>
      <title><![CDATA[財(cái)經(jīng)]]></title>
      <link>http://mc.cz001.com.cn/images/menu/23_active.png</link>
      <category>0</category>
      <description>描述詳細(xì)信息的</description>
      <pubDate>2012-01-09</pubDate>
    </item>

建好后,我們命名為rssxml.xml,然后放到項(xiàng)目的根目錄下:

然后我們可以建立兩個(gè)實(shí)體類:

1、RSSFeed,與完整的xml文檔相對應(yīng);

2、RSSItem,與item標(biāo)簽內(nèi)的信息相對應(yīng)。

這樣在解析xml時(shí),我們就可以把解析出來的信息放到實(shí)體類里,然后直接操作實(shí)體類就可以了。下面給出代碼:

RSSFeed.java

package com.sax.org.entity;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Vector;

public class RSSFeed {
  private String title;
  private int itemcount;
  private List<RSSItem> itemlist;
  
  public RSSFeed(){
    itemlist = new Vector<RSSItem>(0);
  }
  
  /**
   * 負(fù)責(zé)將一個(gè)RSSItem加入到RSSFeed類中
   * @param item
   * @return
   */
  public int addItem(RSSItem item){
    itemlist.add(item);
    itemcount++;
    return itemcount;
  }
  
  public RSSItem getItem(int location){
    return itemlist.get(location);
  }
  
  public List<RSSItem> getAllItems(){
    return itemlist;
  }
  
  /**
   * 負(fù)責(zé)從RSSFeed類中生成列表所需要的數(shù)據(jù)
   * @return
   */
  public List getAllItemForListView(){
    List<Map<String, Object>> data = new ArrayList<Map<String,Object>>();
    int size = itemlist.size();
    for(int i=0 ; i<size ; i++){
      HashMap<String , Object> item = new HashMap<String, Object>();
      item.put(RSSItem.TITLE, itemlist.get(i).getTitle());
      item.put(RSSItem.PUBDATE, itemlist.get(i).getPubdate());
      data.add(item);
    }
    return data;
  }

  public String getTitle() {
    return title;
  }

  public void setTitle(String title) {
    this.title = title;
  }

  public int getItemcount() {
    return itemcount;
  }

  public void setItemcount(int itemcount) {
    this.itemcount = itemcount;
  }

  public List<RSSItem> getItemlist() {
    return itemlist;
  }

  public void setItemlist(List<RSSItem> itemlist) {
    this.itemlist = itemlist;
  }
  
}

RSSItem.java

package com.sax.org.entity;

public class RSSItem {
  public static String TITLE = "title";
  public static String PUBDATE = "pubdate";
  public String title;
  public String description;
  public String link;
  public String category;
  public String pubdate;
  public RSSItem() {
  }
  public String getTitle() {
    return title;
  }
  public void setTitle(String title) {
    this.title = title;
  }
  public String getDescription() {
    return description;
  }
  public void setDescription(String description) {
    this.description = description;
  }
  public String getLink() {
    return link;
  }
  public void setLink(String link) {
    this.link = link;
  }
  public String getCategory() {
    return category;
  }
  public void setCategory(String category) {
    this.category = category;
  }
  public String getPubdate() {
    return pubdate;
  }
  public void setPubdate(String pubdate) {
    this.pubdate = pubdate;
  }
  
  
}

下面就是最最重要的地方了,建立自己的ContentHandler.看下面的代碼:

RSSHandler.java

package com.sax.org.handler;

import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

import com.sax.org.entity.RSSFeed;
import com.sax.org.entity.RSSItem;

public class RSSHandler extends DefaultHandler{
  RSSFeed RssFeed;
  RSSItem RssItem;
  final int RSS_TITLE = 1;
  final int RSS_LINK = 2;
  final int RSS_DESCRIPTION = 3;
  final int RSS_CATEGORY = 4;
  final int RSS_PUBDATE = 5;
  int currentstate = 0;
  
  public RSSHandler(){}
  
  public RSSFeed getFeed(){
    return RssFeed;
  }
  
  @Override
  public void startDocument() throws SAXException {
    // TODO Auto-generated method stub
    RssFeed = new RSSFeed();
    RssItem = new RSSItem();
  }
  
  @Override
  public void endDocument() throws SAXException {
    // TODO Auto-generated method stub
    
  }
  
  @Override
  public void startElement(String uri, String localName, String qName,
      Attributes attributes) throws SAXException {
    // TODO Auto-generated method stub
    if(localName.equals("channel")){
      currentstate = 0;
      return;
    }
    if(localName.equals("item")){
      RssItem = new RSSItem();
      return;
    }
    if(localName.equals("title")){
      currentstate = RSS_TITLE;
      return;
    }
    if(localName.equals("description")){
      currentstate = RSS_DESCRIPTION;
      return;
    }
    if(localName.equals("link")){
      currentstate = RSS_LINK;
      return;
    }
    if(localName.equals("category")){
      currentstate = RSS_CATEGORY;
      return;
    }
    if(localName.equals("pubDate")){
      currentstate = RSS_PUBDATE;
      return;
    }
    currentstate = 0;
  }
  
  @Override
  public void endElement(String uri, String localName, String qName)
      throws SAXException {
    // TODO Auto-generated method stub
    if(localName.equals("item")){
      RssFeed.addItem(RssItem);
      return;
    }
  }
  
  @Override
  public void characters(char[] ch, int start, int length)
      throws SAXException {
    // TODO Auto-generated method stub
    String theString = new String(ch, start, length);
    switch(currentstate){
    case RSS_TITLE:
      RssItem.setTitle(theString);
      currentstate = 0;
      break;
    case RSS_DESCRIPTION:
      RssItem.setDescription(theString);
      currentstate = 0;
      break;
    case RSS_LINK:
      RssItem.setLink(theString);
      currentstate = 0;
      break;
    case RSS_PUBDATE:
      RssItem.setPubdate(theString);
      currentstate = 0;
      break;
    case RSS_CATEGORY:
      RssItem.setCategory(theString);
      currentstate = 0;
      break;
    default:
      return;
    }
  }
}

就上面的代碼分析,實(shí)現(xiàn)一個(gè)ContentHandler一般要一下幾個(gè)步驟:

1、聲明一個(gè)類,繼承DefaultHandler。DefaultHandler是一個(gè)基類,這個(gè)類里面簡單實(shí)現(xiàn)了一個(gè)ContentHandler。我們只需要重寫里面的方法即可。

2、重寫 startDocument() 和 endDocument(),一般解析將正式解析之前的一些初始化工資放到startDocument()里面,收尾的工作放到endDocument()里面。

3、重寫startElement(),XML解析器遇到XML里面的tag時(shí)就會調(diào)用這個(gè)函數(shù)。經(jīng)常在這個(gè)函數(shù)內(nèi)是通過localName倆進(jìn)行判斷而操作一些數(shù)據(jù)。

4、重寫characters()方法,這是一個(gè)回調(diào)方法。解析器執(zhí)行完startElement()后,解析完節(jié)點(diǎn)的內(nèi)容后就會執(zhí)行這個(gè)方法,并且參數(shù)ch[]就是節(jié)點(diǎn)的內(nèi)容。這個(gè)例子里我們根據(jù)currentstate的不同,來判斷當(dāng)前那個(gè)tag的內(nèi)容,并放到合適的實(shí)體類中。

5、重寫endElement()方法,這個(gè)方法與startElement()相對應(yīng),解析完一個(gè)tag節(jié)點(diǎn)后,執(zhí)行這個(gè)方法。再找個(gè)例子中,如果解析一個(gè)item結(jié)束,就將RSSIiem添加到RSSFeed中。

最后我們實(shí)現(xiàn)一個(gè)activity來展現(xiàn)解析的結(jié)果:

 package com.sax.org;

import java.io.IOException;
import java.net.URL;

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

import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;

import android.app.Activity;
import android.os.Bundle;
import android.widget.ListView;
import android.widget.SimpleAdapter;
import android.widget.TextView;

import com.sax.org.entity.RSSFeed;
import com.sax.org.entity.RSSItem;
import com.sax.org.handler.RSSHandler;

public class SAXReaderActivity extends Activity {
  /** Called when the activity is first created. */

  public String rssUrl = "http://mc.cz001.com.cn/a/indexconfig/index.rss";
  public RSSFeed feed;

  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    feed = getFeed(rssUrl);
    showList();
  }

  public RSSFeed getFeed(String rssUrl) {
    try {
// 這里我們實(shí)現(xiàn)了本地解析,所以注掉了這個(gè)取網(wǎng)絡(luò)數(shù)據(jù)的。
//      URL url = new URL(rssUrl);
      SAXParserFactory factory = SAXParserFactory.newInstance();
      SAXParser parser = factory.newSAXParser();
      XMLReader reader = parser.getXMLReader();
      RSSHandler handler = new RSSHandler();
      reader.setContentHandler(handler);
      InputSource is = new InputSource(this.getClassLoader().getResourceAsStream("rssxml.xml"));//取得本地xml文件
      reader.parse(is);
      return handler.getFeed();
    } catch (ParserConfigurationException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    } catch (SAXException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    } catch (IOException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    }
    return null;
  }

  public void showList() {
    ListView rsslistview = (ListView) findViewById(R.id.rssList);
    TextView rsstitle = (TextView) findViewById(R.id.rsstitle);
    if (feed == null) {
      rsstitle.setText("訪問失敗...");
      return;
    }
    SimpleAdapter adapter = new SimpleAdapter(this,
        feed.getAllItemForListView(),
        android.R.layout.simple_list_item_2, new String[] {
            RSSItem.TITLE, RSSItem.PUBDATE }, new int[] {
            android.R.id.text1, android.R.id.text2 });
    rsslistview.setAdapter(adapter);
  }
}

展示下運(yùn)行結(jié)果:

以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • Android性能優(yōu)化getResources()與Binder導(dǎo)致界面卡頓優(yōu)化

    Android性能優(yōu)化getResources()與Binder導(dǎo)致界面卡頓優(yōu)化

    這篇文章主要為大家介紹了Android性能優(yōu)化getResources()與Binder導(dǎo)致界面卡頓優(yōu)化示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-02-02
  • Android編程實(shí)現(xiàn)獲取多媒體庫視頻、音頻、圖片的方法

    Android編程實(shí)現(xiàn)獲取多媒體庫視頻、音頻、圖片的方法

    這篇文章主要介紹了Android編程實(shí)現(xiàn)獲取多媒體庫視頻、音頻、圖片的方法,涉及Android針對多媒體視頻、音頻及相關(guān)專輯圖片、縮略圖等獲取操作實(shí)現(xiàn)技巧,需要的朋友可以參考下
    2018-01-01
  • android調(diào)用C語言實(shí)現(xiàn)內(nèi)存的讀取與修改的方法示例

    android調(diào)用C語言實(shí)現(xiàn)內(nèi)存的讀取與修改的方法示例

    這篇文章主要介紹了android調(diào)用C語言實(shí)現(xiàn)內(nèi)存的讀取與修改的方法示例,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-03-03
  • Android studio kotlin代碼格式化操作

    Android studio kotlin代碼格式化操作

    這篇文章主要介紹了Android studio kotlin代碼格式化操作,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-03-03
  • Android中如何安全地打印日志詳解

    Android中如何安全地打印日志詳解

    日志是我們在日常開發(fā)中必不可少的一部分,下面這篇文章主要給大家介紹了關(guān)于Android中如何安全地打印日志的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們一起來看看吧。
    2017-12-12
  • ViewFlipper實(shí)現(xiàn)文字輪播效果

    ViewFlipper實(shí)現(xiàn)文字輪播效果

    這篇文章主要為大家詳細(xì)介紹了ViewFlipper實(shí)現(xiàn)文字輪播效果,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-08-08
  • Android Studio3.0升級后使用注意事項(xiàng)及解決方法

    Android Studio3.0升級后使用注意事項(xiàng)及解決方法

    這篇文章主要介紹了Android Studio3.0升級后使用注意事項(xiàng)及解決方法,需要的朋友參考下吧
    2017-12-12
  • Android:如何編寫“萬能”的Activity

    Android:如何編寫“萬能”的Activity

    本文主要介紹了編寫“萬能”的Activity的方法與步驟,具有很好的參考價(jià)值,下面跟著小編一起來看下吧
    2017-01-01
  • android實(shí)現(xiàn)注冊頁面開發(fā)

    android實(shí)現(xiàn)注冊頁面開發(fā)

    這篇文章主要為大家詳細(xì)介紹了android實(shí)現(xiàn)注冊頁面開發(fā),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-04-04
  • Android輪播圖點(diǎn)擊圖片放大效果的實(shí)現(xiàn)方法

    Android輪播圖點(diǎn)擊圖片放大效果的實(shí)現(xiàn)方法

    這篇文章主要給大家介紹了關(guān)于Android輪播圖點(diǎn)擊圖片放大效果的實(shí)現(xiàn)方法,文中通過示例代碼介紹的非常詳細(xì),對各位Android開發(fā)者們具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-08-08

最新評論

大冶市| 浮梁县| 新泰市| 乐清市| 巴林右旗| 崇文区| 濮阳市| 三台县| 威宁| 通道| 富阳市| 柳州市| 白玉县| 泸水县| 贡山| 将乐县| 合阳县| 江华| 鹤庆县| 石泉县| 扶风县| 丹寨县| 绵阳市| 莱芜市| 彩票| 呼图壁县| 彭阳县| 化州市| 通州区| 横峰县| 贵溪市| 化隆| 富源县| 灌阳县| 长汀县| 寿阳县| 紫阳县| 工布江达县| 阿拉善右旗| 淄博市| 五指山市|