您的位置:首页 > 移动开发 > Android开发

Android:SAX解析XML文件

2014-09-03 09:27 381 查看
SAX解析XML文件主要通过一个类DefaultHandler来实现,在这个类中重写四个方法;startDocument()、startElement(String uri, String localName, String qName,Attributes attributes)、characters(char[] ch, int start, int length)、endElement(String uri, String localName,
String qName)。由上述四个方法可以看出,其解析过程是一个个元素解析下去的。

首先自定义一个XML文件:Student.xml,注意是新建file而不是xml。

<?xml version="1.0" encoding="utf-8"?>
<students>
	<student id="1">
		<name>张三</name>
		<sex>男</sex>
		<age>18</age>
	</student>
	<student id="2">
		<name>李四</name>
		<sex>女</sex>
		<age>19</age>
	</student>
	<student id="3">
		<name>王五</name>
		<sex>男</sex>
		<age>20</age>
	</student>
</students>
然后新建一个student类

package com.example.xml_sax_demo_1;
public class Student {
	private int id;
	private String name;
	private String sex;
	private int age;
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public String getSex() {
		return sex;
	}
	public void setSex(String sex) {
		this.sex = sex;
	}

	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}

}
接下来是最重要一步,新建一个类继承DefaultHandler

package com.example.xml_sax_demo_1;
import java.util.ArrayList;
import java.util.List;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
import android.R.integer;

public class SAXForHandler extends DefaultHandler {
	private List<Student> list;  //将解析的数据放在一个List里面
	private Student student;
	private String tagName;   //存放元素名称
	public List<Student> getList() {
		return list;
	}
	@Override
	public void startDocument() throws SAXException {
		list = new ArrayList<Student>();   //开始解析时实例化list
	}
	@Override
	public void startElement(String uri, String localName, String qName,
			Attributes attributes) throws SAXException {
		if (qName.equals("student")) {                  //每个元素都是一个element    
			student = new Student();                //例如上面xml文件中的student、name、sex、age
			// 获取student节点上的id属性值          
			student.setId(Integer.parseInt(attributes.getValue(0)));    //属性和文本有所不同
		}
		this.tagName = qName;                           //将元素名称赋给标志,为下一步做准备
	}
	@Override
	public void endElement(String uri, String localName, String qName)
			throws SAXException {
		if (qName.equals("student")) {                 //如果是student说明我们解析完了一项数据
			this.list.add(this.student);
		}
		this.tagName = null;                           //将标志置为null
	}
	@Override
	public void characters(char[] ch, int start, int length)
			throws SAXException {
		if (this.tagName != null) {       //如果tagName不为null,之前看过一篇文章,元素前的空白处也是会被解析的。
			String date = new String(ch, start, length);   //开始存放数据
			if (this.tagName.equals("name")) {
				this.student.setName(date);
			} else if (this.tagName.equals("sex")) {
				this.student.setSex(date);
			} else if (this.tagName.equals("age")) {
				this.student.setAge(Integer.parseInt(date));
			}
		}
	}
}


以解析第一项数据为例:

<students>
	<student id="1">
		<name>张三</name>
		<sex>男</sex>
		<age>18</age>
	</student>


整个流程是:startDocument:实例化list → startElement:元素名为student,将其属性赋给student的字段id,tagName = student → endElement: tagName = null → startElement:tagName = name → characters:元素名为name,将数据赋给student相应字段 → endElement:tagName = null → ....... → endElement:tagName为student,将一项数据存放在list里面。可以这样理解:遇到<type>就是startElement,遇到</type>就是endElement。
最后在activity里面通过一个Button来解析数据,其中用到几个类。

package com.example.xml_sax_demo_1;

import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

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

import org.xml.sax.SAXException;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserFactory;

import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.util.Xml;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;

public class MainActivity extends ActionBarActivity {

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		Button button = (Button) findViewById(R.id.button);
		button.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View arg0) {
				// TODO Auto-generated method stub
				try {
					readXML();
				} catch (Exception e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		});
	}

	private void readXML() throws Exception {
		SAXParserFactory spf = SAXParserFactory.newInstance();
		SAXParser parser = spf.newSAXParser();
		SAXForHandler parseXml = new SAXForHandler(); // 实例化解析类
		InputStream stream = this.getClass().getClassLoader()
				.getResourceAsStream("Student.xml"); // 获得输入流
		parser.parse(stream, parseXml); // 两个参数,一个是输入流,一个是解析类对象。
		List<Student> list = parseXml.getList();
		for (Student student : list) {
			System.out.println(student.getId() + " " + student.getName() + " "
					+ student.getSex() + " " + student.getAge());
		}
	}
}


结果:



小结:注意xml文件的解析过程,完全自己写的demo一直会出现inputstream can not be null的错误,估计是XML写得有问题~~
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: