android 使用SAX解析xml

android 提供了三种解析xml的方式,分别是sax,dom,pull,

pull是android独有的,在以前Java学习中没有出现过,dom和sax java中一直使用,如dom4j就是使用的sax.

接下来我们学习sax在android系统中的学习。

第一步:我们编写一个person.xml文件放到classpath下,内容如下:

<?xml version="1.0" encoding="UTF-8"?>
<persons>
 <person id="23">
   <name>张三</name>
   <age>30</age> 
  </person> 
  <person id="20">
    <name>李四</name>
     <age>25</age>
  </person>
</persons> 
第二步:我们编写对应的Person.java 实体:

public class Person {
	private int id;
	private String name;
	private int age;
        getters();
        setters();

第三步:编写解析代码,实现如下:

package com.hkrt.action;

import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

import com.hkrt.domain.Person;

/**
 * 使用SAX (simple api for xml )解析xml
 * 基于事件驱动,不需要加载整个文件。
 * @author Administrator
 */
public class SAXService {

	public List<Person> personService(InputStream inStream) throws Exception {
		SAXParserFactory factory = SAXParserFactory.newInstance();
		SAXParser parser = factory.newSAXParser();
		PersonDefaultHandler handler = new PersonDefaultHandler();
		parser.parse(inStream, handler);
		inStream.close();
		return handler.getPersons();
	}

	private final class PersonDefaultHandler extends DefaultHandler {
		/**记录解析后的所有person 集合*/
		private List<Person> persons = null;
		private Person currentPerson;

		public List<Person> getPersons() {
			return persons;
		}

		@SuppressWarnings("unused")
		public void setPersons(List<Person> persons) {
			this.persons = persons;
		}
		//定义一个标记变量,标记当前的Xml文件被解析到哪个标签  
		private String tagName = null;
		//第一步执行的方法
		@Override
		public void startDocument() throws SAXException {
			persons = new ArrayList<Person>();
		}
		 /** 
         * 解析XML时,当开始读到一个元素标签开始时,执行下面方法 
         */
		@Override
		public void startElement(String uri, String localName, String qName,Attributes attr) throws SAXException {
			 //判断标签名是否为person,是的话创建一个Person对象,并将其id属性拿出来,赋值到person对象中  
			if ("person".equals(localName)) {
				currentPerson = new Person();
				currentPerson.setId(Integer.parseInt(attr.getValue("id")));

			}
			tagName = localName;
		}

		/** 解析XML时,当开始读到一个文本元素时,执行下面方法  */  
		@Override
		public void characters(char[] ch, int start, int length)throws SAXException {
			  //判断此文本元素是在一个 有效的标签体里面的     例:正确:<name>文本元素</name>  错误: 文本元素<name></name>
			if (tagName != null) {
				String data = new String(ch, start, length);
				if ("name".endsWith(tagName)) {
					currentPerson.setName(data);
				} else if ("age".endsWith(tagName)) {
					currentPerson.setAge(Short.parseShort(data));
				}
			}
		}
		  /** 
         * 解析XML时,当读到结束一个元素标签时,执行下面方法 
         */ 
		@Override
		public void endElement(String uri, String localName, String qName)throws SAXException {
			if ("person".equals(localName)) {
				persons.add(currentPerson);
				currentPerson = null;
			}
			tagName = null;

		}
	}
}

第四步:进行代码测试,我们这里使用android带的junit的实现,具体包已在android中集成,我们不需要额外添加。

  • 在AndoirManifest.xml 添加junit测试环境:  <uses-library android:name="android.test.runner" /> <instrumentation android:name="android.test.InstrumentationTestRunner"
      android:targetPackage="换成Activity 下的包" android:label="Tests for My App" />
  • 编写测度代码
public class PersonTest extends AndroidTestCase {
	private static final String TAG="PersonTest";
	public void testSAXService()throws Throwable{
	   SAXService saxservice=new SAXService();
	   InputStream inStream=this.getClass().getClassLoader().getResourceAsStream("person.xml");
	   List <Person> persons=saxservice.personService(inStream);
	   for(Person p:persons){
		Assert.assertNotNull(p);//junit 断言,不为空LogCat 输出的结果没找到
	    Log.i(TAG,p.toString());//LogCat 输出的结果是I
	    System.err.println(p);//LogCat 输出的结果是W
	   }
	}
}

第五步:启动模拟器,进行Andoird JUnit Test 。



测试结果:



原文地址:https://www.cnblogs.com/java20130726/p/3218360.html