Android开发--XML文件的解析的三种方法

在Android平台上可以使用Document Object Model(DOM)、Simple API for XML(SAX)和Android附带的pull解析器解析XML文件。

要解析的river.xml 如下:

<?xml version="1.0" encoding="utf-8"?>
<rivers>
 <river name="灵渠" length="605">
     <introduction>
      灵渠在广西壮族自治区兴安县境内,是世界上最古老的运河之一,有着“世界古代水利建筑明珠”的美誉。灵渠古称秦凿渠、零渠、陡河、兴安运河,于公元前214年凿成通航,距今已2217年,仍然发挥着功用。
     </introduction>
      <imageurl>
      http://imgsrc.baidu.com/baike/pic/item/389aa8fdb7b8322e08244d3c.jpg
     </imageurl>
   </river> 
   
   <river name="胶莱运河" length="200">
     <introduction>
      胶莱运河南起黄海灵山海口,北抵渤海三山岛,流经现胶南、胶州、平度、高密、昌邑和莱州等,全长200公里,流域面积达5400平方公里,南北贯穿山东半岛,沟通黄渤两海。胶莱运河自平度姚家村东的分水岭南北分流。南流由麻湾口入胶州湾,为南胶莱河,长30公里。北流由海仓口入莱州湾,为北胶莱河,长100余公里。
     </introduction>
      <imageurl>
      http://imgsrc.baidu.com/baike/pic/item/389aa8fdb7b8322e08244d3c.jpg
     </imageurl>
   </river>
   
   <river name="苏北灌溉总渠" length="168"> 
     <introduction>
      位于淮河下游江苏省北部,西起洪泽湖边的高良涧,流经洪泽,青浦、淮安,阜宁、射阳,滨海等六县(区),东至扁担港口入海的大型人工河道。全长168km。
     </introduction>
      <imageurl>
      http://imgsrc.baidu.com/baike/pic/item/389aa8fdb7b8322e08244d3c.jpg
     </imageurl>
   </river>
 </rivers>

三种方式解析的结果是一样的,效果图如下:




下面附上代码:

1.River.java:

public class River {

	private String name;
	private int length;
	private String introduction;
	private String imageurl;
	
	public River(){
		
	}
	
	public River(String name, int length, String introduction, String imageurl){
		this.name = name;
		this.length = length;
		this.introduction = introduction;
		this.imageurl = imageurl;
	}
	
	@Override
	public String toString() {
		return "River [name=" + name + ", length=" + length + ", introduction="
				+ introduction + ", imageurl=" + imageurl + "]";
	}

	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getLength() {
		return length;
	}
	public void setLength(int length) {
		this.length = length;
	}
	public String getIntroduction() {
		return introduction;
	}
	public void setIntroduction(String introduction) {
		this.introduction = introduction;
	}
	public String getImageurl() {
		return imageurl;
	}
	public void setImageurl(String imageurl) {
		this.imageurl = imageurl;
	}
	
}


2.MainActivity.java:

说明:定义了三个按钮和一个列表,并对三个按钮设置点击事件。

public class MainActivity extends Activity {

	private Button domParserBt = null;
	private Button saxParserBt = null;
	private Button pullParserBt = null;
	private ListView riverList = null;
	private RiverAdapter riverAdapter = null;

	private InputStream inputStream = null;
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);

		domParserBt = (Button) findViewById(R.id.DOMParserBt);
		saxParserBt = (Button) findViewById(R.id.SAXParserBt);
		pullParserBt = (Button) findViewById(R.id.PULLParserBt);
		riverList = (ListView) findViewById(R.id.lv);
		
		inputStream = MainActivity.class.getClassLoader().getResourceAsStream("river.xml");

		domParserBt.setOnClickListener(new DomParserButtonListener());
		saxParserBt.setOnClickListener(new SaxParserButtonListener());
		pullParserBt.setOnClickListener(new PullParserButtonListener());
	}

	private class DomParserButtonListener implements OnClickListener{

		@Override
		public void onClick(View v) {
			try {
				List<River> rivers = XmlParserService
						.getRiverListDomParser(inputStream);
				riverAdapter = new RiverAdapter(MainActivity.this, rivers);
				riverList.setAdapter(riverAdapter);

			} catch (Exception e) {
				e.printStackTrace();
				Toast.makeText(MainActivity.this, "xml解析失败", 0).show();
			}
		}
		
	}
	
	private class SaxParserButtonListener implements OnClickListener{

		@Override
		public void onClick(View v) {
			try {
				List<River> rivers = XmlParserService
						.getRiverListSaxParser(inputStream);
				riverAdapter = new RiverAdapter(MainActivity.this, rivers);
				riverList.setAdapter(riverAdapter);

			} catch (Exception e) {
				e.printStackTrace();
				Toast.makeText(MainActivity.this, "xml解析失败", 0).show();
			}
		}
		
	}
	
	private class PullParserButtonListener implements OnClickListener {

		@Override
		public void onClick(View v) {
			try {
				List<River> rivers = XmlParserService
						.getRiverListPullParser(inputStream);
				riverAdapter = new RiverAdapter(MainActivity.this, rivers);
				riverList.setAdapter(riverAdapter);

			} catch (Exception e) {
				e.printStackTrace();
				Toast.makeText(MainActivity.this, "xml解析失败", 0).show();
			}
		}

	}

}

3.XmlParserService.java:

说明:包含三个方法,分别是每个按钮点击事件中调用的解析方法,而且由于方法不依赖类特定的实例,所以定义为静态类。

public class XmlParserService {

	public static List<River> getRiverListDomParser(InputStream is) throws Exception{
		DocumentBuilder documentBuilder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
		Document document = documentBuilder.parse(is);
		
		List<River> rivers = null;
		River river = null;
		
		//找到根Element
		Element root = document.getDocumentElement();
		NodeList nodes = root.getElementsByTagName("river");
		rivers = new ArrayList<River>();
		for (int i = 0; i < nodes.getLength(); i++) {
			river = new River();
			//获取river元素节点
			Element riverElement = (Element) nodes.item(i);
			//获取river中name和length属性值
			river.setName(riverElement.getAttribute("name"));
			river.setLength(Integer.parseInt(riverElement.getAttribute("length")));
			//获取river下introduction标签
			Element introductionElement = (Element) riverElement.getElementsByTagName("introduction").item(0);
			river.setIntroduction(introductionElement.getFirstChild().getNodeValue());
			//获取river下imageurl标签
			Element imageurlElement = (Element) riverElement.getElementsByTagName("imageurl").item(0);
			river.setImageurl(imageurlElement.getFirstChild().getNodeValue());
			
			rivers.add(river);
		}
		is.close();
		return rivers;
	}
	
	public static List<River> getRiverListSaxParser(InputStream is) throws Exception{
		SAXParserFactory saxFactory = SAXParserFactory.newInstance();
		SAXParser saxParser = saxFactory.newSAXParser();
		XmlContentHandler handler = new XmlContentHandler();
		saxParser.parse(is, handler);
		is.close();
		return handler.getRivers();
	}
	
	public static List<River> getRiverListPullParser(InputStream is) throws Exception{
		XmlPullParser pullParser = Xml.newPullParser();
		pullParser.setInput(is, "utf-8");
		
		List<River> rivers = null;
		River river = null;
		int type = pullParser.getEventType();
		while(type != pullParser.END_DOCUMENT){
			switch (type) {
			case XmlPullParser.START_TAG:
				if("rivers".equals(pullParser.getName())){
					rivers = new ArrayList<River>();	
				}else if("river".equals(pullParser.getName())){
					river = new River();
					String name = pullParser.getAttributeValue(0);
					int length = Integer.parseInt(pullParser.getAttributeValue(1));
					river.setName(name);
					river.setLength(length);
				}else if("introduction".equals(pullParser.getName())){
					String introduction = pullParser.nextText();
					river.setIntroduction(introduction);
				}else if("imageurl".equals(pullParser.getName())){
					String imageurl = pullParser.nextText();
					river.setImageurl(imageurl);
				}
				break;

			case XmlPullParser.END_TAG:
				if("river".equals(pullParser.getName())){
					rivers.add(river);
				}
				break;
			}
			type = pullParser.next();
		}
		is.close();
		return rivers;
	}
}

4.XmlContentHandler.java:

说明:SAX解析方法使用了DefaultHandler,所以定义了次类继承DefaultHandler。

注意:下面代码中使用了StringBuffer,使用普通的方法在characters方法中处理标签的内容时,characters方法会调用多次,后来参考了http://blog.csdn.net/feng88724/article/details/7013675这片文章,才解决了问题。

public class XmlContentHandler extends DefaultHandler {

	public static final String TAG = "XmlContentHandler";

	private StringBuilder sb = new StringBuilder();

	private List<River> rivers = null;
	private River river = null;

	public List<River> getRivers() {
		return rivers;
	}

	@Override
	public void characters(char[] ch, int start, int length)
			throws SAXException {
		Log.i(TAG, "解析内容:" + new String(ch, start, length));
		sb.append(ch, start, length);
	}

	@Override
	public void endDocument() throws SAXException {
		super.endDocument();
		Log.i(TAG, "文档解析完毕。");
	}

	@Override
	public void endElement(String uri, String localName, String qName)
			throws SAXException {
		super.endElement(uri, localName, qName);
		Log.i(TAG, localName + "解析完毕");
		String content = sb.toString();
		if ("river".equals(localName)) {
			rivers.add(river);
		}if(("introduction").equals(localName)){
			river.setIntroduction(content);
		}else if(("imageurl").equals(localName)){
			river.setImageurl(content);
		}
	}

	@Override
	public void startDocument() throws SAXException {
		Log.i(TAG, "开始解析... ...");
	}

	@Override
	public void startElement(String uri, String localName, String qName,
			Attributes attributes) throws SAXException {
		Log.i(TAG, "解析元素:" + localName);
		if (localName.equals("rivers")) {
			rivers = new ArrayList<River>();
		} else if (localName.equals("river")) {
			river = new River();
			river.setName(attributes.getValue(0));
			river.setLength(Integer.parseInt(attributes.getValue(1)));
		}
		sb.setLength(0);
	}

}

5.RiverAdapter.java:

public class RiverAdapter extends BaseAdapter{

	private LayoutInflater mInflater;
	private List<River> riverList = Collections.emptyList();
	
	public RiverAdapter(Context context, List<River> riverList){
		this.mInflater = LayoutInflater.from(context);
		this.riverList = riverList;
	}
	
	@Override
	public int getCount() {
		return riverList.size();
	}

	@Override
	public Object getItem(int position) {
		return riverList.get(position);
	}

	@Override
	public long getItemId(int position) {
		// TODO Auto-generated method stub
		return position;
	}

	@Override
	public View getView(int position, View convertView, ViewGroup parent) {
		convertView = mInflater.inflate(R.layout.river_item, null);
		RiverHolder riverHolder = new RiverHolder();
		riverHolder.riverName = (TextView) convertView.findViewById(R.id.river_name);
		riverHolder.riverLength = (TextView) convertView.findViewById(R.id.river_length);
		riverHolder.riverIntroduction = (TextView) convertView.findViewById(R.id.river_introduction);
		
		River river = riverList.get(position); 
		if(river != null){
			riverHolder.riverName.setText(river.getName());
			riverHolder.riverLength.setText(river.getLength() + "");
			riverHolder.riverIntroduction.setText(river.getIntroduction());
		}
		return convertView;
	}

	public class RiverHolder{
		public TextView riverName;
		public TextView riverLength;
		public TextView riverIntroduction;
	}
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值