使用SAX解析XML文档

发表时间:2017-05-10 14:06:22 浏览量( 16 ) 留言数( 0 )

学习目标:

1、了解Java的历史

2、为什么要学习Java语言

3、端正学习态度


学习过程:

一、Dom和Sax的区别

1、DOM是用与平台和语言无关的方式表示XML文档的官方W3C标准。以层次结构组织的节点或信息片断的集合。这个层次结构允许开发人员在树中寻找特定信息。分析该结构通常需要加载整个文档和构造层次结构,然后才能做任何工作。DOM以及广义的基于树的处理具有几个优点。首先,由于树在内存中是持久的,因此可以修改它以便应用程序能对数据和结构作出更改。它还可以在任何时候在树中上下导航,而不是像SAX那样是一次性的处理。DOM使用起来也要简单得多。   

2、SAX处理的优点非常类似于流媒体的优点。分析能够立即开始,而不是等待所有的数据被处理。这对于大型文档来说是个巨大的优点。事实上,应用程序甚至不必解析整个文档 。SAX在概念上与DOM完全不同,这种读入也就SAX的解析过程被称为事件驱动型,而DOM被称作文档驱动。通常,SAX还比它的替代者DOM快许多,因此在一般开发中被优先采用。

相比之下,DOM比较适合在内存比较大,而且可能需要多次操作这个XML文件的情况下使用。而SAX方式比较适合内存有限,比如手机设备使用,一般解析完成之后,不需要多次反复的操作这个XML文件的情况下使用。

二、使用SAX解析XML

1、新建一个Student.xml和对应的javaBean对象。

Student.xml文件内容如下:

>  
    <>  
        <>002 
        <>刘保 
        <>50 
    student>  
    <>  
        <>003 
        <>曾志伟 
        <>30 
    student>  
students>

对应的javaBean对象使用上一节可的Student对象,

 public class Student {
	private int id;
	private String name;
	private int age;
	private List addresses;
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	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 List getAddresses() {
		return addresses;
	}
	public void setAddresses(List addresses) {
		this.addresses = addresses;
	}
}

2、新建一个MyHandler类,继承DefaultHandler。实现基于事件驱动的方式解析XML。这个类是解析的核心代码,代码如下:

package com.dao;

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

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

import com.pojo.Student;

public class MyHandler extends DefaultHandler{
	
	private List students;
	private Student student=null;
	private StringBuffer sb;

	public List getStudents() {
		return students;
	}

	//开始解析时候触发
	@Override
	public void startDocument() throws SAXException {
		System.out.println("开始解析");
		//初始化工作
		students=new ArrayList();
		sb=new StringBuffer();
		super.startDocument();
	}

	//当开始解析某个元素时触发
	@Override
	public void startElement(String uri, String localName, String qName,
			Attributes attributes) throws SAXException {
		
		System.out.println(qName);
		// localName  对应元素名称
		if(qName.equals("student")){
			student=new Student();
		}
		
		//清空读取元素的内容
		sb.setLength(0);
		super.startElement(uri, localName, qName, attributes);
	}

	@Override
	public void characters(char[] ch, int start, int length)
			throws SAXException {
		// TODO Auto-generated method stub
		super.characters(ch, start, length);
		
		sb.append(ch,start,length);
		
	}
	
	//当某个元素结束是触发
	@Override
	public void endElement(String uri, String localName, String qName)
			throws SAXException {
		
		if(qName.equals("student")){
			students.add(student);
			student=null;
		}
		
		if(student!=null){
			if(qName.equals("id")){
				student.setId(Integer.parseInt(sb.toString()));
			}else if(qName.equals("name")){
				student.setName(sb.toString());
			}else if(qName.equals("age")){
				student.setAge(Integer.parseInt(sb.toString()));
			}
		}
		super.endElement(uri, localName, qName);
	}

	//文档解析完毕后触发
	@Override
	public void endDocument() throws SAXException {
		// TODO Auto-generated method stub
		super.endDocument();
	}

}

3、实现类。定义SaxXml类,使用上面的MyHandler类解析,实现代码如下:

 public class SaxXml {

	public List readXML(InputStream in) {
		List students = new ArrayList();

		SAXParserFactory factory = SAXParserFactory.newInstance();
		try {
			SAXParser parser = factory.newSAXParser();
			MyHandler myHandler = new MyHandler();
			// 解析
			parser.parse(in, myHandler);

			students = myHandler.getStudents();

		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		return students;
	}

}

4、测试。

在SaxXml类中添加一个main方法,测试是否能解析成功。

 public static void main(String[] args) throws FileNotFoundException {

		FileInputStream fileInputStream = new FileInputStream(new File(
				"./xml/Students.xml"));

		SaxXml saxXml = new SaxXml();
		List students = saxXml.readXML(fileInputStream);

		for (int i = 0; i < students.size(); i++) {
			Student student = students.get(i);
			System.out.println(student.getName() + ":" + student.getAge());
		}

	}

输出如下:

attcontent/97521d5d-0bdc-4957-aba6-e6770d7ef69e.png

可以全部解析成功。