解析XML文件之使用SAM解析器

前端之家收集整理的这篇文章主要介绍了解析XML文件之使用SAM解析器前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

XML是一种常见的数据传输方式,所以在开发中,我们会遇到对XML文件进行解析的时候,本篇主要介绍使用SAM解析器,对XML文件进行解析。

SAX解析器的优点是显而易见的,那就是SAX并不需要将所有的文档都加载内存之后才进行解析,SAX是事件驱动机制的,也就是碰到元素节点、文本节点、文档节点的时候,都会触发一定的事件,我们只需要在相应的回调事件里面进行相应的处理就可以了。因为这个特点,所以SAX解析占用的内存比较少,其他的解析方式,比如下一节要介绍的DOM解析器,则占用内存比较多。在解析比较小的XML文件的时候,区别不是很大,大家哪种顺手就可以用哪种。但是当需要解析的文档达到几百K以上的时候,还是推荐使用SAX解析器或者是PULL解析器。这几种XML的解析方式,我都会在以后的文章中进行介绍,今天重点看SAX解析器。

下面是我们要进行解析的文件格式

<?xml version="1.0" encoding="UTF-8"?>
<persons>
	<person id="23">
		<name>liming</name>
		<age>30</age>
	</person>
	<person id="20">
		<name>lixiangmei</name>
		<age>25</age>
	</person>
</persons>

下面是我们的实体类

public class Person {
	private Integer id;
	private String name;
	private Short age;
	
	public Person(){}
	
	public Person(Integer id,String name,Short age) {
		this.id = id;
		this.name = name;
		this.age = age;
	}
	
	public Integer getId() {
		return id;
	}
	public void setId(Integer id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public Short getAge() {
		return age;
	}
	public void setAge(Short age) {
		this.age = age;
	}
	@Override
	public String toString() {
		return "Person [age=" + age + ",id=" + id + ",name=" + name + "]";
	}
	
}

我们定义一个SAM解析器,对内容进行解析

/**
 * 使用SAX对XML文件进行解析
 * 
 * @author zhaokaiqiang
 * 
 */
public class SaxResolve {

	public List<Person> getPersons(InputStream inputStream) throws Exception {

		//获取SAXParser对象
		SAXParser parser = SAXParserFactory.newInstance().newSAXParser();
		//实例化我们的解析器
		PersonHandler handler = new PersonHandler();
		//开始对输入流解析
		parser.parse(inputStream,handler);
		//关闭输入流
		inputStream.close();
		//返回结果
		return handler.getPersons();
	}

	private class PersonHandler extends DefaultHandler {

		private List<Person> persons;
		private Person person = null;
		private String tag = null;

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

		// 当读取到xml文件的开始部分时,对persons进行初始化
		@Override
		public void startDocument() throws SAXException {
			persons = new ArrayList<Person>();
		}

		// 这个方法对元素节点进行解析,如我们数据中的<person>、<age>、<name>都属于元素节点
		// 当读取到person节点时,对Person对象进行初始化,同时获取属性节点的值,并赋值给id,
		// 记录现在的节点的名称,即localName,用于Person节点内部节点的解析
		@Override
		public void startElement(String uri,String localName,String qName,Attributes attributes) throws SAXException {
			if (localName.equals("person")) {
				person = new Person();
				person.setId(new Integer(attributes.getValue(0)));
			}
			tag = localName;
		}

		// 这个回调方法用于对文本节点进行解析,如<age>30</age>里面的30就是属于文本节点,
		// 我们根据元素节点tag的取值,取出里面的文本节点,然后对person进行赋值
		@Override
		public void characters(char[] ch,int start,int length)
				throws SAXException {

			if (tag != null) {
				String data = new String(ch,start,length);
				if ("name".equals(tag)) {
					person.setName(data);
				} else if ("age".equals(tag)) {
					person.setAge(new Short(data));
				}
			}

		}

		/*
		 * 当到达一个元素节点的结束时 比如 
		 * <person id="20"> 
		 * 	<name>lixiangmei</name>
		 * 	<age>25</age> 
		 * </person>
		 * 当到达这里的</person>节点,就会出发下面的事件,我们在这个回调方法里面将解析出的person对象
		 * 添加到persons里面,并且将person和tag进行初始化,进行下一个person节点的解析
		 */
		@Override
		public void endElement(String uri,String qName)
				throws SAXException {
			if (localName.equals("person")) {
				persons.add(person);
				person = null;
			}
			tag = null;
		}

	}

}

因为注释比较详细,所以不过多解析,下面我们使用单元测试,对解析进行测试

//测试SAX解析
	public void testSax() throws Exception {
		//从xml文件获取输入流
		InputStream inputStream = getClass().getClassLoader()
				.getResourceAsStream("persons.xml");
		//获取解析出的对象
		List<Person> persons = new SaxResolve().getPersons(inputStream);
		//打印
		for (Person p : persons) {
			Log.d(TAG,p.toString());
		}

	}

下面是解析结果

原文链接:https://www.f2er.com/xml/298550.html

猜你在找的XML相关文章