日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > Android >内容正文

Android

Android实例RSS客户端开发(2)--解析XML文件

發布時間:2024/1/17 Android 37 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Android实例RSS客户端开发(2)--解析XML文件 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

?

介紹完RSS之后,下面開始講解如何解析RSS文件。因為RSS是基于XML的,所以我們就直接介紹如何解析XML文件。

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

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

  優點:整個文檔讀入內存,方便操作:支持修改、刪除和重現排列等多種功能。

  缺點:將整個文檔讀入內存中,保留了過多的不需要的節點,浪費內存和空間。

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

為了解決DOM解析存在的問題,就出現了SAX解析。其特點為:

  優點:不用實現調入整個文檔,占用資源少。尤其在嵌入式環境中,如android,極力推薦使用SAX解析。

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

  使用場合:機器有性能限制。

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

基于事件驅動的處理模式主要是基于事件源和事件處理器(或者叫監聽器)來工作的。一個可以產生事件的對象叫做事件源,而一個可以針對事件做出響應的對象就被叫做事件處理器。

在SAX接口中,事件源是org.xml.sax包中的XMLReader,他通過parse()方法開始解析XML文檔,并根據文檔內容產生事件。而事件處理器則是org.xml.sax包中的ContentHandler、DTDHandler、ErrorHandler,以及EntityResolver這四個接口。他們分別處理事件源在解析過程中產生不同類的事件(其中DTDHandler為解析文檔DTD時所用)。

SAX是一種占用內存少且解析速度快的解析器,它采用的是事件啟動,它不需要解析完整個文檔,而是按照內容順序 看文檔某個部分是否符合xml語法,如果符合就觸發相應的事件,所謂的事件就是些回調方法(callback),這些方法 定義在ContentHandler中,下面是其主要方法:
startDocument:當遇到文檔的時候就觸發這個事件 調用這個方法 可以在其中做些預處理工作
startElement: (String namespaceURI,String localName,String qName,Attributes atts)當遇開始標簽的時候就會觸發這個方法。
endElement(String uri,String localName,String name):當遇到結束標簽時觸發這個事件,調用此法可以做些善后工作。
charachers(char [] ch,int start,int length):當遇到xml內容時觸發這個方法,用new String(ch,start,length)可以接受內容。?

?二?建立pojo類?

在解析之前,我們需要建立pojo類來對應RSS中的元素。首先是RSS feed,我們知道<channel> 元素用于描述 RSS feed,但它不是描述RSS的重點,它下面的三個必須子元素<title><link><description>是描述feed的主要信息。因為我們在解析之前就

事先獲取了RSS地址,所以在這里我們就不需要建立一個RSS的link了。主要建立link,item列表以及description,因為是標題,所以把description就換成時間來表達,一般的RSS也是這樣做的。如圖:





下面是建立的RSSFeed:

public class RSSFeed?
{
private String title = null;標題
private String pubdate = null;發布日期
private int itemcount = 0;//用于計算列表數目
private List<RSSItem> itemlist;聲明一個RSSItem類型的泛型集合類List對象itemlist,用于描述列表?item
?public RSSFeed()
{
itemlist = new Vector(0); 構造函數初始化itemlist
}
public int addItem(RSSItem item)
{
itemlist.add(item);
itemcount++;
return itemcount;
}
public RSSItem getItem(int location)
{
return itemlist.get(location);
}
public List getAllItems()
{
return itemlist;
}
public List getAllItemsForListView(){
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;
}
int getItemCount()
{
return itemcount;
}
public void setTitle(String title)
{
this.title = title;
}
public void setPubDate(String pubdate)
{
this.pubdate = pubdate;
}
public String getTitle()
{
return title;
}
public String getPubDate()
{
return pubdate;
}
}

建立完RSSFeed 類后,我們開始建立?RSSItem
public static final String TITLE="title";
public static final String PUBDATE="pubdate";
private String title = null;
private String description = null;
private String link = null;
private String category = null;
private String pubdate = null;
? ? ? ?

? ? ? ? public RSSItem()
{
}
public void setTitle(String title)
{
this.title = title;
}
public void setDescription(String description)
{
this.description = description;
}
public void setLink(String link)
{
this.link = link;
}
public void setCategory(String category)
{
this.category = category;
}
public void setPubDate(String pubdate)
{
this.pubdate = pubdate;
}
public String getTitle()
{
return title;
}
public String getDescription()
{
return description;
}
public String getLink()
{
return link;
}
public String getCategory()
{
return category;
}
public String getPubDate()
{
return pubdate;
}
public String toString()
{
if (title.length() > 20)
{
return title.substring(0, 42) + "...";
}
return title;
}
}

三 解析

新建helper類RSSHandler,用于對rss進行xml解析,并將解析結果包裝為RSSFeed和RSSItem對象,方便在ui界面中顯示:

public class RSSHandler extends DefaultHandler?
{

RSSFeed rssFeed;//用于保存解析過程中的channel
RSSItem rssItem;//用于保存解析過程中的item
String lastElementName = "";?//標記變量,用于標記在解析過程中我們關心的幾個標簽,若不是我們關心的標簽,記做?0
final int RSS_TITLE = 1;//若是title標簽,記做?1,注意有兩個title,但我們都保存在itemtitle成員變量中
final int RSS_LINK = 2;//若是link標簽,記做?2
final int RSS_DESCRIPTION = 3;//若是description標簽,記做?3
final int RSS_CATEGORY = 4;//若是category標簽,記做?4
final int RSS_PUBDATE = 5;?//若是pubdate標簽,記做?5,注意有兩個pubdate,但我們都保存在itempubdate成員變量中
int currentstate = 0;

? ? ? ? public RSSHandler(){}
public RSSFeed getFeed()
{
return rssFeed;//通過這個方法把解析結果封裝在?RSSFeed?對象中并返回
}

?//下面通過重載?DefaultHandler??5?個方法來實現?sax?解析
public void startDocument() throws SAXException
{

? ? ? ? ? ? ? ? //這個方法在解析xml文檔的一開始執行,一般我們需要在該方法中初始化解析過程中有可能用到的變量
rssFeed = new RSSFeed();
rssItem = new RSSItem();
? ? ? ? }
public void endDocument() throws SAXException
{

//這個方法在整個xml文檔解析結束時執行,一般需要在該方法中返回或保存整個文檔解析解析結果,但由于

?????//我們已經在解析過程中把結果保持在rssFeed中,所以這里什么也不做


}
public void startElement(String namespaceURI, String localName,String qName, Attributes atts) throws SAXException
{

//這個方法在解析標簽開始標記時執行,一般我們需要在該方法取得標簽屬性值,但由于我們的rss文檔

?????//中并沒有任何我們關心的標簽屬性,因此我們主要在這里進行的是設置標記變量currentstate,以

?????//標記我們處理到哪個標簽


if (localName.equals("channel"))
{//channel這個標簽沒有任何值得我們關心的內容,所以currentstate置為0
currentstate = 0;
return;
}
if (localName.equals("item"))
{

//若是item標簽,則重新構造一個RSSItem,從而把已有(已經解析過的)item數據扔掉,當

?//然事先是已經保存到rssFeed的itemlist集合中了


rssItem = new RSSItem();
return;
}
if (localName.equals("title"))
{

//若是title標簽,置currentstate為1,表明這是我們關心的數據,這樣在characters

?//方法中會把元素內容保存到rssItem變量中


currentstate = RSS_TITLE;
return;
}
if (localName.equals("description"))
{

//若是description標簽,置currentstate為3,表明這是我們關心的數據,這樣在characters

?//方法中會把元素內容保存到rssItem變量中


currentstate = RSS_DESCRIPTION;
return;
}
if (localName.equals("link"))
{

//若是link標簽,置currentstate為2,表明這是我們關心的數據,這樣在characters

?//方法中會把元素內容保存到rssItem變量中


currentstate = RSS_LINK;
return;
}
if (localName.equals("category"))
{

//若是category標簽,置currentstate為4,表明這是我們關心的數據,這樣在characters

?//方法中會把元素內容保存到rssItem變量中


currentstate = RSS_CATEGORY;
return;
}
if (localName.equals("pubDate"))
{

//若是pubDate標簽,置currentstate為5,表明這是我們關心的數據,這樣在characters

?//方法中會把元素內容保存到rssItem變量中


currentstate = RSS_PUBDATE;
return;
}

currentstate = 0;//如果不是上面列出的任何標簽,currentstate0,我們不關心
}

public void endElement(String namespaceURI, String localName, String qName) throws SAXException
{


//如果解析一個item節點結束,就將rssItem添加到rssFeed中。
if (localName.equals("item"))
{
rssFeed.addItem(rssItem);
return;

}
}

public void characters(char ch[], int start, int length)
{//這個方法在解析標簽內容(即開始標記-結束標記之間的部分)時執行,一般我們在里這獲取元素體內容
String theString = new String(ch,start,length);?//獲取元素體內容
switch (currentstate)
{//根據currentstate標記判斷這個元素體是屬于我們關心的哪個元素
case RSS_TITLE:
rssItem.setTitle(theString);//若是title元素,放入rssItemtitle屬性
currentstate = 0;
break;
case RSS_LINK:
rssItem.setLink(theString);//若是link元素,放入rssItemlink屬性
currentstate = 0;
break;
case RSS_DESCRIPTION:
rssItem.setDescription(theString);
currentstate = 0;
break;
case RSS_CATEGORY:
rssItem.setCategory(theString);
currentstate = 0;
break;
case RSS_PUBDATE:
rssItem.setPubDate(theString);
currentstate = 0;
break;
default:
return;
}

}

}

之后就可以按照一定的步驟來進行解析了,具體如下:

private RSSFeed getFeed(String urlString)
? ? {
? ? try
? ? {
? ? ? URL url = new URL(urlString);
? ? ? ? ? SAXParserFactory factory = SAXParserFactory.newInstance();??//?構建Sax解析工廠
? ? ? ? ? ?SAXParser parser = factory.newSAXParser();?//?使用Sax解析工廠構建Sax解析器
? ? ? ? ? ?XMLReader xmlreader = parser.getXMLReader();???//?使用Sax解析器構建xml?Reader
? ? ? ? ? ?
? ? ? ? ? ?RSSHandler rssHandler = new RSSHandler();?//?構建自定義的RSSHandler作為xml?Reader的處理器(或代理)
? ? ? ? ? ?xmlreader.setContentHandler(rssHandler);?? ??//?構建自定義的RSSHandler作為xml?Reader的處理器(或代理)


? ? ? ? ? ?InputSource is = new InputSource(url.openStream()); ? ???//?使用url打開流,并將流作為xml?Reader的輸入源并解析
? ? ? ? ? ?xmlreader.parse(is);
??
? ? ? ? ? ?return rssHandler.getFeed();? ???//?將解析結果作為?RSSFeed?對象返回
? ? }
? ? catch (Exception ee)
? ? {


? ? return null;
? ? }
? ? }

RSS文件的解析就介紹到這里,之后我們開始實現如何在列表里顯示RSS內容了。

轉載于:https://www.cnblogs.com/android-html5/archive/2012/06/01/2533929.html

總結

以上是生活随笔為你收集整理的Android实例RSS客户端开发(2)--解析XML文件的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 欧美一级片在线播放 | 日韩精品一区二区av | 少妇人妻偷人精品视频蜜桃 | 美女av一区| 亚欧av在线| 91国自啪| 国产精品第一区 | 国产a三级 | 一色综合| 97综合| 视频在线观看一区二区三区 | 中文字幕亚洲乱码熟女1区2区 | 美日韩一二三区 | 日本美女一区二区三区 | 91精品国产aⅴ一区 黄色a网 | 亚洲欧美国产一区二区三区 | 欧美日韩中文在线观看 | 亚洲国产电影在线观看 | av片网站 | 久久精品一区二区三 | 国产一区在线免费观看 | 午夜视频入口 | 一本大道久久a久久综合婷婷 | 亚洲一区h | 成人av在线电影 | 殴美性生活| 人人精品视频 | 少妇无码一区二区三区免费 | 天堂网av中文字幕 | 看黄色一级大片 | 操女人的逼逼 | 久久一区二区电影 | 一级黄色片免费在线观看 | 九热在线视频 | 欧美三级不卡 | 成人爱爱网站 | 亚洲一区二区三区四区五区午夜 | 国产在线中文字幕 | 久久精品偷拍视频 | 日本裸体网站 | 无码精品国产一区二区三区免费 | 精品国产精品网麻豆系列 | 青青色在线视频 | 亚洲天堂最新 | 亚洲欧洲日韩av | 一级特黄aa大片免费播放 | 一级黄色片免费看 | 少妇太紧太爽又黄又硬又爽 | 国产精品大屁股白浆一区 | 少妇太紧太爽又黄又硬又爽 | 免费成人在线观看视频 | 调教撅屁股啪调教打臀缝av | 亚洲乱码国产乱码精品精的特点 | 国产99对白在线播放 | 欧美视频日韩视频 | av资源导航 | a v视频在线播放 | 日韩黄色网 | 欧美成人做爰猛烈床戏 | 国产日日夜夜 | 人妻在线一区二区三区 | 欧美三级精品 | 电影寂寞少女免费观看 | 阿v天堂在线观看 | 麻豆乱码国产一区二区三区 | av一区二区三区在线 | 精品一区二区三区av | 青青青草视频在线 | 黄色成人免费观看 | 亚洲美女视频网 | 欧美私人网站 | 欧美日本一道本 | 欧美黑人孕妇孕交 | 色婷婷久久五月综合成人 | 美女被揉胸视频 | 国产成人综合网 | 超碰在线观看99 | 人人草人人看 | 国产91一区在线精品 | 亚州福利 | 香蕉婷婷 | caopeng在线视频 | 国产山村乱淫老妇女视频 | 国产亚洲精品久久久久久 | 91日批| 中文字幕色 | 欧美丰满老熟妇aaaa片 | 2024av| 国产资源精品 | 日韩中文娱乐网 | 四虎啪啪| 日本一级淫片1000部 | 日本视频网 | 精品日韩视频 | 日本精品久久久久久久 | 奇米四色影视 | 国产视频综合 | 99久久精品国产毛片 | 日本一道本 |