java-SAX解析XML示例

   JAVA 解析 XML 通常有两种方式:DOM 和SAX。DOM(文档对象模型)是W3C标准,提供了标准的解析方式,但其解析效率一直不尽如人意,这是因为DOM解析XML文档时,把所有内容一次性的装载入内存,并构建一个驻留在内存中的树状结构(节点数)。如果需要解析的XML文档过大,或者我们只对该文档中的一部分感兴趣,这样就会引起性能问题。
   SAX(simple API for XML)是一种XML解析的替代方法。相比于DOM,SAX是一种速度更快,更有效的方法。它逐行扫描文档,一边扫描一边解析。而且相比于DOM,SAX可以在解析文档的任意时刻停止解析,但任何事物都有其相反的一面,对于SAX来说就是操作复杂。

    SAX采用事件处理的方式解析XML文件,通常涉及两个部分:解析器和事件处理器:
——解析器可以使用JAXP的API创建,创建出SAX解析器后,就可以指定解析器去解析某个XML文档。解析器采用SAX方式在解析某个XML文档时,它只要解析到XML文档的一个组成部分,都会去调用事件处理器的一个方法,解析器在调用事件处理器的方法时,会把当前解析到的xml文件内容作为方法的参数传递给事件处理器。
——事件处理器由程序员编写,程序员通过事件处理器中方法的参数,就可以很轻松地得到sax解析器解析到的数据,从而可以决定如何对数据进行处理。

package cd.itcast.day3;

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

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

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

public class SaxParserDemo {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		saxParse();
	}

	public static void saxParse() {
		// 得到SAX解析工厂实例
		SAXParserFactory spf = SAXParserFactory.newInstance();
		try {
			// 得到SAX解析器
			SAXParser sp = spf.newSAXParser();
			// 得到XML读取器
			// XMLReader xr = sp.getXMLReader();
			// 设置XML内容处理器
			// xr.setContentHandler(new MyContentHandler());
			// xr.parse("D:\\Java\\WorkSpace\\JavaDemo\\src\\cd\\itcast\\day3\\student.xml");
			
			List<Student> list = new ArrayList<Student>();
			
			//直接采用SAX解析器的解析方法,传入一个DefaultHandler实例
			sp.parse(
					"D:\\Java\\WorkSpace\\JavaDemo\\src\\cd\\itcast\\day3\\student.xml",
					new MyDefaultHander(list));

			for (Student stu : list) {
				System.out.println(stu);
			}
		} catch (ParserConfigurationException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (SAXException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

	}

	//DefaultHandler实现了ContentHandler的方法,因此可以声明一个类继承DefaultHandler,并覆盖我们需要的方法即可.
	static class MyDefaultHander extends DefaultHandler {
		// 通过够咱函数传递给内部的List,接收解析出来的Student内容.
		private List<Student> stuList = null;
		
		// 定义一个标记,获取元素的标签名,根据标签名称做不同的处理.
		private String tagName = null;
		//Student实例,每解析出一个student元素,将解析出来的内容设置到stu对象,并添加到list中.
		private Student stu = null;

		public MyDefaultHander(List<Student> stuList) {
			this.stuList = stuList;
		}

		@Override
		public void startDocument() throws SAXException {
			// TODO Auto-generated method stub
			System.out.println("文档开始");
		}

		@Override
		public void endDocument() throws SAXException {
			// TODO Auto-generated method stub
			System.out.println("文档结束");
		}

		@Override
		public void startElement(String uri, String localName, String qName,
				Attributes atts) throws SAXException {
			// TODO Auto-generated method stub
			// System.out.println("元素开始:" + qName);
			tagName = qName; // 元素一开始,记录标记
			if ("student".equals(qName)){
				stu = new Student();
				stu.setId(Integer.parseInt(atts.getValue("id")));
			}
		}

		@Override
		public void endElement(String uri, String localName, String qName)
				throws SAXException {
			// TODO Auto-generated method stub
			// System.out.println("元素结束:" + qName);
			tagName = null; // 清空标记
			if ("student".equals(qName)){
				stuList.add(stu);
			}
		}

		@Override
		public void characters(char[] ch, int start, int length)
				throws SAXException {
			// TODO Auto-generated method stub
			// System.out.println("开始处理字符:" + new String(ch, start, length));
			if ("name".equals(tagName)) {
				stu.setName(new String(ch, start, length));	
			}
			else if ("sex".equals(tagName)) {
				stu.setSex(new String(ch, start, length));
			}
			else if ("age".equals(tagName)) {
				stu.setAge(Integer.parseInt(new String(ch, start, length)));	
			}
		}
	}

	//采用XMLReader必须要覆盖ContentHandler的方法,不方便.
	static class MyContentHandler implements ContentHandler {
		@Override
		public void setDocumentLocator(Locator locator) {
			// TODO Auto-generated method stub

		}

		@Override
		public void startDocument() throws SAXException {
			// TODO Auto-generated method stub
			System.out.println("文档开始");
		}

		@Override
		public void endDocument() throws SAXException {
			// TODO Auto-generated method stub
			System.out.println("文档结束");
		}

		@Override
		public void startPrefixMapping(String prefix, String uri)
				throws SAXException {
			// TODO Auto-generated method stub

		}

		@Override
		public void endPrefixMapping(String prefix) throws SAXException {
			// TODO Auto-generated method stub

		}

		@Override
		public void startElement(String uri, String localName, String qName,
				Attributes atts) throws SAXException {
			// TODO Auto-generated method stub
			System.out.println("元素开始:" + qName);
		}

		@Override
		public void endElement(String uri, String localName, String qName)
				throws SAXException {
			// TODO Auto-generated method stub
			System.out.println("元素结束:" + qName);
		}

		@Override
		public void characters(char[] ch, int start, int length)
				throws SAXException {
			// TODO Auto-generated method stub
			System.out.println("开始处理字符:" + new String(ch, start, length));
		}

		@Override
		public void ignorableWhitespace(char[] ch, int start, int length)
				throws SAXException {
			// TODO Auto-generated method stub

		}

		@Override
		public void processingInstruction(String target, String data)
				throws SAXException {
			// TODO Auto-generated method stub

		}

		@Override
		public void skippedEntity(String name) throws SAXException {
			// TODO Auto-generated method stub

		}
	}
}

你可能感兴趣的:(java-SAX解析XML示例)