天天看點

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這些方法。

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

	}

}