利用SAX、DOM和Pull实现对schools.xml的解析并进行单元测试

首先给出schools.xml文件的代码:

<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/css" href="school.css"?>
<!DOCTYPE schools SYSTEM "schools.dtd">
<schools>

<school level="middle-school">
	<teacher>
		<teacherName>Tom</teacherName>
		<teacherAge>34</teacherAge>
	</teacher>
	<student>
		<studentName>Jack</studentName>
		<studentAge>28</studentAge>
	</student>
	<student>
		<studentName>Mary</studentName>
		<studentAge>22</studentAge>
	</student>
	<student>
		<studentName>John</studentName>
		<studentAge>23</studentAge>
	</student>
</school>

<school level="primary-school">
	<teacher>
		<teacherName>Tom</teacherName>
		<teacherAge>34</teacherAge>
	</teacher>
	<student>
		<studentName>Jack</studentName>
		<studentAge>21</studentAge>
	</student>
	<student>
		<studentName>Mary</studentName>
		<studentAge>25</studentAge>
	</student>
	<student>
		<studentName>Jhon</studentName>
		<studentAge>26</studentAge>
	</student>

</school>

</schools>

首先定义三个javabean

school.java

package cn.csdn.domain;

import java.util.List;

public class School {
	private String level;
	private Teacher teacher;
	private List<Student> student;
	public School() {
		super();
		// TODO Auto-generated constructor stub
	}
	public School(String level, Teacher teacher, List<Student> student) {
		super();
		this.level = level;
		this.teacher = teacher;
		this.student = student;
	}
	public String getLevel() {
		return level;
	}
	public void setLevel(String level) {
		this.level = level;
	}
	public Teacher getTeacher() {
		return teacher;
	}
	public void setTeacher(Teacher teacher) {
		this.teacher = teacher;
	}
	public List<Student> getStudent() {
		return student;
	}
	public void setStudent(List<Student> student) {
		this.student = student;
	}
	@Override
	public String toString() {
		return "School [level=" + level + ", teacher=" + teacher + ", student="
				+ student + "]";
	}
	
	
}
Teahcer.java

package cn.csdn.domain;

public class Teacher {
	private String name;
	private int age;
	public Teacher() {
		super();
		// TODO Auto-generated constructor stub
	}
	public Teacher(String name, int age) {
		super();
		this.name = name;
		this.age = age;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	@Override
	public String toString() {
		return "Teacher [name=" + name + ", age=" + age + "]";
	}
	
}

Student.java

package cn.csdn.domain;

public class Student {
	private String name;
	private int age;
	public Student() {
		super();
		// TODO Auto-generated constructor stub
	}
	public Student(String name, int age) {
		super();
		this.name = name;
		this.age = age;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	@Override
	public String toString() {
		return "Student [name=" + name + ", age=" + age + "]";
	}
	
}


1、用sax解析该文件

SAX是基于事件驱动的。当然android的事件机制是基于回调函数的,在用SAX解析xml文档时候,在读取到文档开始和结束标签时候就会回调一个事件,在读取到其他节点与内容时候也会回调一个事件。


SchooleHandler.java

package cn.csdn.service;

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.util.Log;
import cn.csdn.domain.School;
import cn.csdn.domain.Student;
import cn.csdn.domain.Teacher;

public class SchoolHandler extends DefaultHandler {
	List<School> schoolList=null;
	List<Teacher> teacherList=null;
	List<Student> studentList=null;
	School school=null;
	Teacher teacher=null;
	Student student=null;
	String elementTag = null;
	
	public void characters(char[] ch, int start, int length)
			throws SAXException {
		String data = new String(ch, start, length);
		if (elementTag != null&&teacher!=null) {
			if("teacherName".equals(elementTag)){
				teacher.setName(data);
				//Log.i("TAG",teacher.toString());
			}else if("teacherAge".equals(elementTag)){
				teacher.setAge(Integer.valueOf(data));
				//Log.i("TAG",teacher.toString());
			}
		}
		if(elementTag!=null&&student!=null){
			if("studentName".equals(elementTag)){
				student.setName(data);
			}else if("studentAge".equals(elementTag)){
				//Log.i("TAG",data);
				student.setAge(Integer.parseInt(data));
			}
		}
	}

	public void endDocument() throws SAXException {
	}

	public void endElement(String uri, String localName, String qName)
			throws SAXException {
		if("teacher".equals(localName)){
			//Log.i("TAG",teacher.toString());
			teacherList.add(teacher);
			school.setTeacher(teacher);
			teacher=null;
		}else if("student".equals(localName)){
			studentList.add(student);
			//school.setStudent(studentList);
			student=null;
		}else if("school".equals(localName)){
			school.setStudent(studentList);
			schoolList.add(school);
			studentList=null;
			school=null;
		}
		elementTag = null;
	}

	public void startDocument() throws SAXException {
		schoolList=new ArrayList<School>();
		teacherList=new ArrayList<Teacher>();
		studentList=new ArrayList<Student>();
	}

	public void startElement(String uri, String localName, String qName,
			Attributes attributes) throws SAXException {
		if("school".equals(localName)){
			school=new School();
			school.setLevel(attributes.getValue(0));
			studentList=new ArrayList<Student>();
			//Log.i("TAG",attributes.getValue(0));
		}else if("teacher".equals(localName)){
			teacher=new Teacher();
			//Log.i("TAG",teacher.toString());
			if(teacher!=null){
			//	Log.i("TAG",teacher.toString());
			}
		}else if("student".equals(localName)){
			student=new Student();
		}
		elementTag = localName;
	}

	public List<School> getSchooList(){
		return schoolList;
	}
}

SaxSchoolService.java

package cn.csdn.service;

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

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

import cn.csdn.domain.School;

public class SAXSchoolService {

	public List<School> getPersonList(InputStream in) throws Exception{
		
		//得到SAX哭器的工厂对象
		SAXParserFactory factory=SAXParserFactory.newInstance();
		//让工厂对象去创建器对象
		SAXParser parser=factory.newSAXParser();
		
		//创建DefaultHandler对象
		SchoolHandler handler=new SchoolHandler();	
		//使用parserr 的parser(inputstream in,DefaultHanderHandler handler);
		parser.parse(in, handler);
		List<School> personList=handler.getSchooList();
		return personList;
		
	}
}

2、用dom解析文件

 DOM方式解析xml是先把xml文档都读到内存中,然后再用DOM API来访问树形结构,并获取数据的,但是这样一来,如果xml文件很大呢?手机CPU处理能力当然不能与PC机器比,因此在处理效率方面就相对差了,当然这是对于其他方式处理xml文档而言。


DomSchoolService.java

package cn.csdn.service;

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

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import android.util.Log;
import cn.csdn.domain.School;
import cn.csdn.domain.Student;
import cn.csdn.domain.Teacher;

public class DomSchoolService {
	public static List<School> getSchoolList(InputStream in) throws Exception{
		List<School> schoolList=new ArrayList<School>();
		
		DocumentBuilderFactory factory=DocumentBuilderFactory.newInstance();
		DocumentBuilder builder=factory.newDocumentBuilder();
		Document document=builder.parse(in);
		
		//取得根结点
		Element root=document.getDocumentElement();
		NodeList nodes=root.getElementsByTagName("school");
		for(int i=0;i<nodes.getLength();i++){
			Element schoolElement=(Element) nodes.item(i);
			School school=new School();
			Teacher teacher=new Teacher();
			Student student=new Student();
			List<Student> studentList=new ArrayList<Student>();
			//为school添加level属性
			school.setLevel(schoolElement.getAttribute("level"));
			NodeList chileNodes = schoolElement.getChildNodes();
			// 遍历孩子节点,忽略文本节点,保留并处理元素节点
			for (int j = 0; j < chileNodes.getLength(); j++) {
				Node childNode = chileNodes.item(j);				
				if("teacher".equals(childNode.getNodeName())){
					NodeList teacherNodes=childNode.getChildNodes();
					for(int t=0;t<teacherNodes.getLength();t++){
						Node teacherNode=teacherNodes.item(t);
						if (teacherNode.getNodeType() == Node.ELEMENT_NODE) {
							if("teacherName".equals(teacherNode.getNodeName())){
								teacher.setName(teacherNode.getFirstChild().getNodeValue());
							}else if("teacherAge".equals(teacherNode.getNodeName())){
								String age=teacherNode.getFirstChild().getNodeValue();
								teacher.setAge(Integer.parseInt(age));
							}
						}
						school.setTeacher(teacher);
					}
					
				}else if("student".equals(childNode.getNodeName())){
					NodeList studentNodes=childNode.getChildNodes();
					student=new Student();
					for(int s=0;s<studentNodes.getLength();s++){
						//System.out.println(s);
						Node studentNode=studentNodes.item(s);
						if(studentNode.getNodeType()==Node.ELEMENT_NODE){
							if("studentName".equals(studentNode.getNodeName())){
								student.setName(studentNode.getFirstChild().getNodeValue());								
							}else if("studentAge".equals(studentNode.getNodeName())){
								String age=studentNode.getFirstChild().getNodeValue();
								student.setAge(Integer.parseInt(age));	
								//Log.i("TAG",student.toString());
								studentList.add(student);
								student=null;
							}
						}
					}					
				}
				
			}
			school.setStudent(studentList);
			studentList=null;
			schoolList.add(school);
		}
		return schoolList;		
	}
}

3、用Pull解析文件

PULL方式读xml回调方法返回的是数字。

   读取到xml的声明返回      START_DOCUMENT;
   读取到xml的结束返回      END_DOCUMENT ;
   读取到xml的开始标签返回 START_TAG
   读取到xml的结束标签返回 END_TAG
   读取到xml的文本返回      TEXT


PullShoolService.java

package cn.csdn.service;

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

import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlSerializer;

import android.util.Xml;
import cn.csdn.domain.School;
import cn.csdn.domain.Student;
import cn.csdn.domain.Teacher;

public class PullSchoolService {
	public static List<School> getSchoolList(InputStream in) throws Exception{
		List<School> schoolList=null;
		XmlPullParser parser=Xml.newPullParser();
		parser.setInput(in,"utf-8");
		School school=null;
		Teacher teacher=null;
		Student student=null;
		List<Student> studentList=null;
		int eventType=parser.getEventType();
		while(eventType!=XmlPullParser.END_DOCUMENT){
			switch(eventType){
			case XmlPullParser.START_DOCUMENT:
				schoolList=new ArrayList<School>();
				break;
			case XmlPullParser.START_TAG:
				if("school".equals(parser.getName())){
					school=new School();
					school.setLevel(parser.getAttributeValue(0));
					studentList=new ArrayList<Student>();
				}else if("teacherName".equals(parser.getName())){
					teacher=new Teacher();
					teacher.setName(parser.nextText());
				}else if("teacherAge".equals(parser.getName())){
					teacher.setAge(Integer.parseInt(parser.nextText()));
				}else if("studentName".equals(parser.getName())){
					student=new Student();
					student.setName(parser.nextText());
				}else if("studentAge".equals(parser.getName())){
					student.setAge(Integer.parseInt(parser.nextText()));
				}
				break;
			case XmlPullParser.END_TAG:
				if("teacher".equals(parser.getName())&&teacher!=null){
					school.setTeacher(teacher);
					teacher=null;
				}else if("student".equals(parser.getName())&&student!=null){
					studentList.add(student);
					student=null;
				}else if("school".equals(parser.getName())&&school!=null){
					school.setStudent(studentList);
					schoolList.add(school);
					school=null;
					studentList=null;
				}
				break;
			}
			// next方法的导致进行下一个节点的解析,同时返回下一个节点解析的事件类型代码、
			eventType = parser.next();
		}
		return schoolList;
	}
	public static void writerPersonList(List<School> schoolList,Writer writer) throws Exception{
		XmlSerializer serializer=Xml.newSerializer();
		serializer.setOutput(writer);
		//定入
		serializer.startDocument("utf-8", true);
		//写入根标签的起始
		serializer.startTag(null, "schools");
		
		for(School school:schoolList){
			serializer.startTag(null, "school");
			//添加id属性
			serializer.attribute(null, "level", school.getLevel());
			serializer.startTag(null, "teacher");
			//老师姓名
			serializer.startTag(null, "teacherName");
			serializer.text(school.getTeacher().getName());			
			serializer.endTag(null, "teacherName");
			//老师年龄
			serializer.startTag(null, "teacherAge");
			serializer.text(school.getTeacher().getAge()+"");
			serializer.endTag(null, "teacherAge");	
			serializer.endTag(null, "teacher");
			
			for(Student list:school.getStudent()){
				serializer.startTag(null, "student");
				//学生姓名
				serializer.startTag(null, "studentName");
				serializer.text(list.getName());			
				serializer.endTag(null, "studentName");
				//学生年龄
				serializer.startTag(null, "studentAge");
				serializer.text(list.getAge()+"");
				serializer.endTag(null, "studentAge");	
				serializer.endTag(null, "student");
			}
			serializer.endTag(null, "school");
		}		
		//结束标签
		serializer.endTag(null, "schools");
		//结束文档的写入
		serializer.endDocument();
		
		writer.flush();
		writer.close();
	}
}
4、写测试类

SchoolXmlActivity.java

package cn.csdn.activity;

import java.io.File;
import java.io.FileWriter;
import java.io.InputStream;
import java.io.Writer;
import java.util.ArrayList;
import java.util.List;

import android.test.AndroidTestCase;
import android.util.Log;
import cn.csdn.domain.School;
import cn.csdn.domain.Student;
import cn.csdn.domain.Teacher;
import cn.csdn.service.DomSchoolService;
import cn.csdn.service.PullSchoolService;
import cn.csdn.service.SAXSchoolService;

public class SchoolXmlActivity extends AndroidTestCase {
	public void testSAX() throws Exception{
		List<School> schoolList=null;
		SAXSchoolService service=new SAXSchoolService();
		InputStream in=this.getClass().getClassLoader().getResourceAsStream("schools.xml");
		schoolList=service.getPersonList(in);
		for(School list:schoolList){
			Log.i("TAG",list.toString());
			Log.i("TAG",list.getStudent().toString());
		}
	}
	public void domTest() throws Exception{
		List<School> schoolList=null;
		InputStream in=this.getClass().getClassLoader().getResourceAsStream("schools.xml");
		schoolList=DomSchoolService.getSchoolList(in);
		for(School list:schoolList){
			//Log.i("TAG",List.toString());
			Log.i("TAG",list.getStudent().toString());
			
		}
	}
	
	public void pullTest() throws Exception{
		InputStream in=this.getClass().getClassLoader().getResourceAsStream("schools.xml");
		List<School> schoolList=PullSchoolService.getSchoolList(in);
		for(School list:schoolList){
			//Log.i("TAG",List.toString());
			Log.i("TAG",list.getStudent().toString());
		}
		
	}
	public void pullsave() throws Throwable{
		List<School> schoolList=new ArrayList<School>();
		School school=new School();
		Teacher teacher=new Teacher();
		List<Student> studentList=new ArrayList<Student>();
		
		teacher.setName("Mary");
		teacher.setAge(30);
		studentList.add(new Student("Tom",20));
		studentList.add(new Student("Jack",22));
		studentList.add(new Student("HeyLey",23));
		
		school.setTeacher(teacher);
		school.setStudent(studentList);
		school.setLevel("middle-school");
		
		schoolList.add(school);
		schoolList.add(new School("primary-school",new Teacher("renhaili",20),studentList));
		
		File file=new File(this.getContext().getFilesDir(),"new_student.xml");
		Writer writer=new FileWriter(file);
		PullSchoolService.writerPersonList(schoolList, writer);
	} 
	
}
源码下载地址:http://download.csdn.net/download/rhljiayou/3934764



评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值