xml解析之SAX解析和PULL解析

一:解析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, EntityResolver 和 ErrorHandler 。實際上只要繼承DefaultHandler 類 ,再覆蓋一部分 處理事件的方法 同樣可以達到相同的效果。 實際上DefaultHandler就是實現了上面的四個事件處理器接口,然後提供了每個抽象方法的默認實現。)

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

DefaultHandler是SAX2 事件處理程序的默認基類。

此模塊(包括源代碼和文檔)位於公共域中,對該模塊不提供擔保有關更多信息,請參閱http://www.saxproject.org

此類可用作 SAX2 應用程序的有用基類:它提供四個核心 SAX2 處理程序類中的所有回調的默認實現:

  • EntityResolver
  • DTDHandler
  • ContentHandler
  • ErrorHandler

應用程序編寫者可以在他們僅需實現部分接口時擴展此類;當應用程序尚未提供其自己的處理程序時解析器編寫者可通過實例化此類來提供默認的處理程序。

此類替換不推薦使用的 SAX1 HandlerBase 類。

*/

創建一個實體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 localName, 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);
		}

	}

}

















發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章