加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

xml解析之SAX解析和PULL解析

发布时间:2020-12-16 09:16:39 所属栏目:百科 来源:网络整理
导读:一:解析user.xml配置文件。 pre name="code" class="html"?xml version="1.0" encoding="UTF-8"?personspersonname张三/nameage30/agesex男/sex/personpersonname李四/nameage32/agesex女/sex/personpersonnamewangwu/nameage30/agesex男/sex/person/person
一:解析user.xml配置文件。
<pre name="code" class="html"><?xml version="1.0" encoding="UTF-8"?>
<persons>
	<person>
		<name>张三</name>
		<age>30</age>
		<sex>男</sex>	
	</person>
	<person>
		<name>李四</name>
		<age>32</age>
		<sex>女</sex>
	</person>
	<person>
		<name>wangwu</name>
		<age>30</age>
		<sex>男</sex>
	</person>
</persons>

 
  
1.SAX解析过程:
创建一个MyHandler类继承DefaultHandler,重写startDocument、startElement、characters、endElement、endDocument这些方法。

/*DefaultHandler

SAX API中主要有四种处理事件的接口,它们分别是ContentHandler,DTDHandler,EntityResolverErrorHandler。实际上只要继承DefaultHandler类 ,再覆盖一部分 处理事件的方法 同样可以达到相同的效果。 实际上就是实现了上面的四个事件处理器接口,然后提供了每个抽象方法的默认实现。)

以下是JDK API 1.6中的原文解释:

DefaultHandler是SAX2 事件处理程序的默认基类。

此模块(包括源代码和文档)位于公共域中,对该模块不提供担保有关更多信息,请参阅 http://www.saxproject.org。

此类可用作 SAX2 应用程序的有用基类:它提供四个核心 SAX2 处理程序类中的所有回调的默认实现:

  • EntityResolver
  • DTDHandler
  • ContentHandler
  • ErrorHandler

应用程序编写者可以在他们仅需实现部分接口时扩展此类;当应用程序尚未提供其自己的处理程序时解析器编写者可通过实例化此类来提供默认的处理程序。

此类替换不推荐使用的 SAX1HandlerBase类。

*/

创建一个实体person类存储解析出来的数据。具体实现代码如下:
person实体类:
package com.qianfeng.saxparser1;

public class Person {
	private String name;
	private int age;
	private String sex;

	public Person() {
		// TODO Auto-generated constructor stub
	}

	public Person(String name,int age,String sex) {
		super();
		this.name = name;
		this.age = age;
		this.sex = sex;
	}

	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;
	}

	public String getSex() {
		return sex;
	}

	public void setSex(String sex) {
		this.sex = sex;
	}

	@Override
	public String toString() {
		return "Person [name=" + name + ",age=" + age + ",sex=" + sex + "]";
	}
	
	

}

Myhandler类
package com.qianfeng.saxparser1;

import java.util.ArrayList;
import java.util.List;

import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

public class MyHandler extends DefaultHandler {
	private List<Person> list;
	private Person person;
	private String tagName;
	//解析到文档开头时执行该方法
	@Override
	public void startDocument() throws SAXException {
		System.out.println("解析到文档开头...");
		list = new ArrayList<Person>();
	}
	
	//解析到开始标签时执行该方法
	@Override
	public void startElement(String uri,String localName,String qName,Attributes attributes) throws SAXException {
		//保存标签名
		tagName = qName;
		System.out.println("解析到开始标签...."+qName);
		if("person".equals(qName))
		{
			person = new Person();
		}
		
	}
	//解析到标签内容时执行该方法
	@Override
	public void characters(char[] ch,int start,int length)
			throws SAXException {
		String content = new String(ch,start,length);
		System.out.println("解析到标签内容...."+content);
		if("name".equals(tagName))
			person.setName(content);
		else if("age".equals(tagName))
			person.setAge(Integer.parseInt(content));
		else if("sex".equals(tagName))
			person.setSex(content);
		
	}
	
	//解析到结束标签时执行该方法
	@Override
	public void endElement(String uri,String qName)
			throws SAXException {
		//注意
		tagName="";//结束标签后边的空白也被看成标签内容,会去执行characters方法
		System.out.println("解析到结束标签...."+qName);
		if("person".equals(qName))
		{
			list.add(person);
		}
	}
	
	//解析到文档结束时执行该方法
	@Override
	public void endDocument() throws SAXException {
		System.out.println("解析到文档结束.....");
	}
    //返回集合
	public List<Person> getList() {
		return list;
	}
	

}

测试主方法:
package com.qianfeng.saxparser1;


import java.io.File;
import java.io.IOException;
import java.util.List;

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

import org.xml.sax.SAXException;

public class Test {

	/**
	 * @param args
	 * @throws SAXException 
	 * @throws ParserConfigurationException 
	 * @throws IOException 
	 */
	public static void main(String[] args) throws ParserConfigurationException,SAXException,IOException {
		
		//创建SAX解析器工厂对象
		SAXParserFactory factory = SAXParserFactory.newInstance();
		
		//创建SAX解析器对象
		SAXParser parser = factory.newSAXParser();
		
		//创建被解析的文件对象
		File file = new File("user.xml");
		
		//创建Handler对象
		MyHandler handler = new MyHandler();
		
		//让解析器去解析文件,并调用handler中的方法
		parser.parse(file,handler);
		
		List<Person> list = handler.getList();
		
		for(Person person:list)
		{
			System.out.println(person);
		}
		
		

	}

}


2.pull解析过程
XmlPull和Sax类似,是基于流(stream)操作文件,然后根据节点事件回调开发者编写的处理程序。因为是基于流的处理,因此Xmlpull和 Sax都比较节约内存资源,不会象Dom那样要把所有节点以对橡树的形式展现在内存中。 但Xmlpull比Sax更简明,而且不需要扫描完整个流。可以使用一个switch对感兴趣的事件进行处理。将switch语句放入while循环中。当parser.next()存在时一直循环执行。
注意:xml中的<?xml version="1.0" encoding="utf-8"?> 这句话要顶格显示,不要留空隙,否则错了很难调试的
在Android中:Pull是Android内置的xml解析器Pull解析器的运行方式与SAX解析器相似。它提供了类似的事件,如:开始元素和结束元素事件,使用parser.next()可以进入下一个元素并触发相应事件。事件将作为数值代码被发送,因此可以使用一个switch对感兴趣的事件进行处理。当元素开始解析时,调用parser.nextText()方法可以获取下一个Text类型节点的值。

过程:创建XmlPullParserFactory工厂,通过工厂获取XmlPullParser解析器,创建要解析的文件,并通过parser.setInput()方法写入解析器(注意编码问题)。具体见代码:

package com.qianfeng.pullparser1;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import org.xmlpull.v1.XmlPullParserFactory;

public class PullParser {
	
	
	public List<Person> pullParser() throws XmlPullParserException,IOException
	{
		List<Person> list = null;
		Person person = null;
		//创建pull解析器工厂对象
		XmlPullParserFactory  factory = XmlPullParserFactory.newInstance();
		
		//创建pull解析器对象
		XmlPullParser parser = factory.newPullParser();
		
		//FileReader fr = new FileReader("user.xml");
		FileInputStream fis = new FileInputStream("user.xml");
		parser.setInput(fis,"utf-8");
		
		//获取解析返回的第一个编号
		int event = parser.getEventType();
		while(event!=XmlPullParser.END_DOCUMENT)
		{
			switch(event)
			{
				case XmlPullParser.START_DOCUMENT:
					 list = new ArrayList<Person>();
					 break;
				case XmlPullParser.START_TAG:
					 //得到标签名称
					String tagName = parser.getName();
					if("person".equals(tagName))
						person = new Person();
					else if("name".equals(tagName))
						person.setName(parser.nextText());
					else if("age".equals(tagName))
						person.setAge(Integer.parseInt(parser.nextText()));//得到开始标签后的数据
					else if("sex".equals(tagName))
						person.setSex(parser.nextText());
					break;
				case XmlPullParser.END_TAG:
					if("person".equals(parser.getName()))
					{
						list.add(person);
						person = null;
					}
					break;
			}
			//得到下一个编号
			event = parser.next();
		}
		return list;
	}

	/**
	 * @param args
	 * @throws IOException 
	 * @throws XmlPullParserException 
	 */
	public static void main(String[] args) throws XmlPullParserException,IOException {
		
//		System.out.println(XmlPullParser.START_DOCUMENT);
//		System.out.println(XmlPullParser.START_TAG);
//		System.out.println(XmlPullParser.END_TAG);
//		System.out.println(XmlPullParser.END_DOCUMENT);
		
		PullParser pullParser = new PullParser();
		List<Person> list = pullParser.pullParser();
		
		for(Person person:list)
		{
			System.out.println(person);
		}

	}

}












(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读