android解析xml-豆瓣电影API的xml解析实例

本文介绍如何使用SAX解析器处理豆瓣电影API返回的XML数据。通过自定义ContentHandler接口,实现对电影信息的逐条解析并存储到Movie对象中。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

    android解析xml一般有两种方法,一种是Document Object Model(DOM)把xml的所有节点写入内存,然后按照Dom方式遍历解析;另一种方式是Simple API for XML(SAX),按顺序读取xml文件,读取的过程中,判断读到的字符是否为合法的xml语句的一部分,如果是则触发相应的回调事件,换而言之,SAX是事件驱动型的,这样就避免占用大量内存,很适合手机的使用。SAX相关的包已经被android附带了,下面我们就试着用SAX来解析豆瓣电影API的xml。

1、查看xml

     豆瓣电影API的接口为:http://api.douban.com/movie/subjects?start-index=0&max-results=2&tag=2012

 start-index:开始的条数;max-results:最大条数;tag:标签

    返回的xml为:

   

<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xmlns:db="http://www.douban.com/xmlns/" xmlns:gd="http://schemas.google.com/g/2005" xmlns:openSearch="http://a9.com/-/spec/opensearchrss/1.0/" xmlns:opensearch="http://a9.com/-/spec/opensearchrss/1.0/">
	<title>带有标签 2012 的条目</title>
	<opensearch:startIndex>1</opensearch:startIndex>
	<opensearch:totalResults>200</opensearch:totalResults>
	<entry>
		<id>http://api.douban.com/movie/subject/6386345</id>
		<title>春嬌與志明</title>
		<category scheme="http://www.douban.com/2007#kind" term="http://www.douban.com/2007#movie"/>
		<author>
			<name>彭浩翔 Ho-Cheung Pang</name>
		</author>
		<link href="http://api.douban.com/movie/subject/6386345" rel="self"/>
		<link href="http://movie.douban.com/subject/6386345/" rel="alternate"/>
		<link href="http://img1.douban.com/spic/s8985924.jpg" rel="image"/>
		<db:attribute name="director">彭浩翔</db:attribute>
		<db:attribute lang="zh_CN" name="aka">春娇与志明</db:attribute>
		<db:attribute name="website">www.mediaasia.com/loveinthebuff</db:attribute>
		<db:attribute name="writer">彭浩翔</db:attribute>
		<db:attribute name="writer">陆以心</db:attribute>
		<db:attribute name="language">粤语</db:attribute>
		<db:attribute name="language">汉语普通话</db:attribute>
		<db:attribute name="imdb">http://www.imdb.com/title/tt2238839/</db:attribute>
		<db:attribute name="country">香港</db:attribute>
		<db:attribute name="country">中国大陆</db:attribute>
		<db:attribute name="pubdate">2012-03-29(香港)</db:attribute>
		<db:attribute name="pubdate">2012-03-30(中国大陆)</db:attribute>
		<db:attribute name="cast">杨千嬅</db:attribute>
		<db:attribute name="cast">余文乐</db:attribute>
		<db:attribute name="cast">杨幂</db:attribute>
		<db:attribute name="cast">徐峥</db:attribute>
		<db:attribute name="cast">谷德昭</db:attribute>
		<db:attribute name="cast">郑伊健</db:attribute>
		<db:attribute name="cast">陈逸宁</db:attribute>
		<db:attribute name="cast">司徒慧焯</db:attribute>
		<db:attribute name="cast">黄晓明</db:attribute>
		<db:attribute name="cast">詹瑞文</db:attribute>
		<db:attribute name="cast">田蕊妮</db:attribute>
		<db:attribute name="cast">王馨平</db:attribute>
		<db:attribute name="cast">郝蕾</db:attribute>
		<db:attribute name="cast">谷祖琳</db:attribute>
		<db:attribute name="cast">王太利</db:attribute>
		<db:attribute name="cast">邵音音</db:attribute>
		<db:attribute name="cast">曾国祥</db:attribute>
		<db:attribute name="cast">尹志文</db:attribute>
		<db:attribute name="cast">彭浩翔</db:attribute>
		<db:attribute name="cast">魏雨琦</db:attribute>
		<db:attribute name="cast">林兆霞</db:attribute>
		<gd:rating average="7.5" max="10" min="0" numRaters="133961"/>
	</entry>
	<entry>
		<id>http://api.douban.com/movie/subject/1866479</id>
		<title>The Avengers</title>
		<category scheme="http://www.douban.com/2007#kind" term="http://www.douban.com/2007#movie"/>
		<author>
			<name>乔斯·韦登 Joss Whedon</name>
		</author>
		<link href="http://api.douban.com/movie/subject/1866479" rel="self"/>
		<link href="http://movie.douban.com/subject/1866479/" rel="alternate"/>
		<link href="http://img1.douban.com/spic/s8904324.jpg" rel="image"/>
		<db:attribute name="director">乔斯·韦登</db:attribute>
		<db:attribute lang="zh_CN" name="aka">复仇者联盟</db:attribute>
		<db:attribute name="website">avengers.marvel.com</db:attribute>
		<db:attribute name="writer">乔斯·韦登</db:attribute>
		<db:attribute name="writer">扎克·佩恩</db:attribute>
		<db:attribute name="language">英语</db:attribute>
		<db:attribute name="imdb">http://www.imdb.com/title/tt0848228/</db:attribute>
		<db:attribute name="country">美国</db:attribute>
		<db:attribute name="pubdate">2012-05-04(美国)</db:attribute>
		<db:attribute name="pubdate">2012-05-05(中国大陆)</db:attribute>
		<db:attribute name="cast">小罗伯特·唐尼</db:attribute>
		<db:attribute name="cast">克里斯·埃文斯</db:attribute>
		<db:attribute name="cast">斯嘉丽·约翰逊</db:attribute>
		<db:attribute name="cast">克里斯·海姆斯沃斯</db:attribute>
		<db:attribute name="cast">杰瑞米·雷纳</db:attribute>
		<db:attribute name="cast">马克·鲁弗洛</db:attribute>
		<db:attribute name="cast">塞缪尔·杰克逊</db:attribute>
		<db:attribute name="cast">汤姆·希德勒斯顿</db:attribute>
		<db:attribute name="cast">斯特兰·斯卡斯加德</db:attribute>
		<db:attribute name="cast">寇碧·史莫德斯</db:attribute>
		<db:attribute name="cast">克拉克·格雷格</db:attribute>
		<db:attribute name="cast">保罗·贝坦尼</db:attribute>
		<db:attribute name="cast">格温妮斯·帕特洛</db:attribute>
		<gd:rating average="8.0" max="10" min="0" numRaters="112004"/>
	</entry>
	<opensearch:itemsPerPage>2</opensearch:itemsPerPage>
</feed>

2、建立一个Movie类,将xml里的每一部电影信息储存至一个实例里。

public class Movie {
	private String singleUrl;
	private String imgUrl;
	private String title;
	private float rating;
	private String director;
	private String cast;
	private String area;
	private String reDate;

	public Movie() {

	}

	public Movie(String singleUrl, String imgUrl, String title, float rating,
			String director, String cast, String area, String reDate) {
		this.singleUrl = singleUrl;
		this.imgUrl = imgUrl;
		this.title = title;
		this.rating = rating;
		this.director = director;
		this.cast = cast;
		this.area = area;
		this.reDate = reDate;
	}

	public String getSingleUrl() {
		return singleUrl;
	}

	public String getImgUrl() {
		return imgUrl;
	}

	public String getTitle() {
		return title;
	}

	public String getDirector() {
		return director;
	}

	public String getCast() {
		return cast;
	}

	public String getArea() {
		return area;
	}

	public void setSingleUrl(String singleUrl) {
		this.singleUrl = singleUrl;
	}

	public void setImgUrl(String imgUrl) {
		this.imgUrl = imgUrl;
	}

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

	public void setDirector(String director) {
		this.director = director;
	}

	public void setCast(String cast) {
		this.cast = cast;
	}

	public void setArea(String area) {
		this.area = area;
	}

	public String getReDate() {
		return reDate;
	}

	public void setReDate(String reDate) {
		this.reDate = reDate;
	}

	public float getRating() {
		return rating;
	}

	public void setRating(float rating) {
		this.rating = rating;
	}

}

3、使用sax处理事件的接口

    一般使用ContentHandler接口,主要有一下事件:

  1. startDocument():开始读取xml时触发
  2. endDocument():读取结束时触发
  3. startElement():开始读取一个标签时触发
  4. characters():读取一行标签内内容时触发
  5. endElement():读取一个标签结束时触发

通常我们继承DefaultHandler类,再重写其中的方法,便可快速实现读取xml;一下是读取豆瓣电影xml的代码:

import java.util.ArrayList;

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

import android.util.Log;

/**
 * @author fddi
 * 
 */
public class MovieHandler extends DefaultHandler {
	private String kEntryElementName = "entry";
	private String kTitleElementName = "title";
	private String kLinkElementName = "link";
	private String kAttrElementName = "attribute";
	private String kDirectorAttrName = "director";
	private String kCastAttrName = "cast";
	private String kRatingElementName = "rating";
	private ArrayList<Movie> movieList;
	private Movie movie;
	private String TAG = "MovieHandler";
	private String attr = "";
	private String title = "";
	private String cast = "";
	private String director = "";

	public ArrayList<Movie> getMovieList() {
		return movieList;
	}

	@Override
	public void endDocument() throws SAXException {
		// TODO Auto-generated method stub
		super.endDocument();
		Log.d(TAG, "end-document");
	}

	@Override
	public void startDocument() throws SAXException {
		// TODO Auto-generated method stub
		super.startDocument();
		movieList = new ArrayList<Movie>();
	}

	@Override
	public void startElement(String uri, String localName, String qName,
			Attributes attributes) throws SAXException {
		// TODO Auto-generated method stub
		super.startElement(uri, localName, qName, attributes);
		if (localName.equalsIgnoreCase(kTitleElementName)) {
			attr = kTitleElementName;
		} else if (localName.equalsIgnoreCase(kEntryElementName)) {
			movie = new Movie();
		} else if (localName.equalsIgnoreCase(kLinkElementName)) {
			String rel = attributes.getValue("rel");
			String url = attributes.getValue("href");
			if (rel.equalsIgnoreCase("self")) {
				movie.setSingleUrl(url);
			} else if (rel.equalsIgnoreCase("image")) {
				movie.setImgUrl(url);
			}
		} else if (localName.equalsIgnoreCase(kRatingElementName)) {
			String rat = attributes.getValue("average");
			float ratf = Float.parseFloat(rat);
			movie.setRating(ratf);
		} else if (localName.equalsIgnoreCase(kAttrElementName)) {
			attr = attributes.getValue("name");
		}
	}

	@Override
	public void characters(char[] ch, int start, int length)
			throws SAXException {
		// TODO Auto-generated method stub
		super.characters(ch, start, length);
		String value = new String(ch, start, length);
		value = value.trim();
		if (attr.equalsIgnoreCase(kTitleElementName)) {
			title = value;
		} else if (attr.equalsIgnoreCase(kDirectorAttrName)) {
			director += value + " ";
		} else if (attr.equalsIgnoreCase(kCastAttrName)) {
			cast += value + " ";
		} else if (attr.equalsIgnoreCase("country")) {
			movie.setArea(value);
		} else if (attr.equalsIgnoreCase("aka")) {
			title += "(" + value + ")";
		} else if (attr.equalsIgnoreCase("area")) {
			movie.setArea(value);
		} else if (attr.equalsIgnoreCase("pubdate")) {
			movie.setReDate(value);
		}
		attr = "";
	}

	@Override
	public void endElement(String uri, String localName, String qName)
			throws SAXException {
		// TODO Auto-generated method stub
		super.endElement(uri, localName, qName);
		if (localName.equalsIgnoreCase(kEntryElementName)) {
			movie.setCast(cast);
			movie.setDirector(director);
			movie.setTitle(title);
			movieList.add(movie);
			Log.d(TAG, "title:" + title);
			cast = "";
			director = "";
			title = "";
		}
	}
}

4、获取内容

实例化SAXParserFactory类,并且给定url,绑定我们先前编写的handler类,便可读出数据

private ArrayList<Movie> xmlResolver(String urlStr) {
		ArrayList<Movie> list = null;
		SAXParserFactory factory = SAXParserFactory.newInstance();
		SAXParser parser;
		MovieHandler handler = new MovieHandler();
		try {
			parser = factory.newSAXParser();
			XMLReader xmlreader = parser.getXMLReader();
			URL url = new URL(urlStr);
			Log.d("bookxml-urls:", urlStr);
			InputSource is = new InputSource(url.openStream());
			Log.d(TAG, "xml:" + is.toString());
			xmlreader.setContentHandler(handler);
			xmlreader.parse(is);
		} catch (ParserConfigurationException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (SAXException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (MalformedURLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		list = handler.getMovieList();
		return list;
	}

返回list,在activity显示;显示方式及源码下载请看这一篇博客:http://blog.youkuaiyun.com/fddinetwork/article/details/7677313



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值