天天看点

使用jaxp进行sax解析

一、sax解析

simple api for xml  社区标准,几乎所有解析器都支持

xml文件->创建sax解析器->事件处理器对xml内容进行处理->读取xml内容

步骤:

1、创建解析工厂;2、创建解析器 ;  3、获取读取器 Xmlreader;   4、对读取器设置内容处理,这里就是要传入指定的事件处理器;  5、完成事件处理,读取xml内容

二、dom与sax解析方法的对比

 dom  在解析过程会在内存中建立一个模型,即针对该xml的生成整个dom树的document对象

*          缺点:消耗内存  如果数据过大,产生较大文档消耗内存,容易导致内存溢出

*          优点:增删改方便快速  只要得到dom文档,就可以快速删除、定位等

*         

*     sax  对xml文件从上往下依次读,读取一行处理一行

*          优点:内存消耗小,解析速度快  允许在读取文档时,不必等到整个文档都装载完才操作

*          缺点:只适合对文档做读取,不适合做增删改    

三、示例说明

     先写一个简单的xml:

dom1.xml

<?xml version="1.1" encoding="UTF-8" standalone="no"?><书架>
	<书>
	<书名 name1="XXXXX" name2="******">沉默世界</书名>
	<作者>张思宁</作者>
	<页数>486</页数>	
	<售价>38</售价>
	</书>
</书架>
           
<pre class="java" name="code">public class saxDemo1 {

	public static void main(String[] args) throws Exception
	{
		//1、创建解析工厂
		SAXParserFactory saxparserfactory = SAXParserFactory.newInstance();
		//2、解析器
		SAXParser Sparser = saxparserfactory.newSAXParser();
		//3、get xmlreader,得到读取器
		XMLReader xreader = Sparser.getXMLReader();
		//4、设置内容处理器;
		//ContentHandler handler = xreader.getContentHandler();     获取处理器,但处理器的函数都是void类型,返回不了信息,则需要复写内部方法
		xreader.setContentHandler(new ListHandler());   //实现ContentHandler,创建对象传入
		//5、读取xml文档的内容
		xreader.parse(new InputSource("src/cn/itcast/xml/dom1.xml"));

		
	}


}
//写好了一个处理器,得到xml文档所有内容
class ListHandler implements ContentHandler
{

	@Override
	public void setDocumentLocator(Locator locator) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void startDocument() throws SAXException {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void endDocument() throws SAXException {
		// TODO Auto-generated method stub
		
	}

	@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+">");     //当前解析的标签名    标签 qName  Attributes 属性
		//打印属性
		System.out.println("属性个数: "+atts.getLength());
		for (int i = 0;i < atts.getLength(); i++)
		{
			if (atts == null)
			{
				break;
			}
			String propName = atts.getLocalName(i);    //属性名称
			//打印属性名称及对应值
			System.out.println("属性"+i+": "+propName+"="+atts.getValue(propName));   
		}
		
		
		
	}

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

以上是对sax解析的示例说明,主要是通过实现接口的方法来创建事件处理器;

以下示例通过实现接口、继承类两种方式进行对比:

public class saxDemo2 {

	public static void main(String[] args) throws ParserConfigurationException, SAXException, IOException {
		//1、创建解析工厂
				SAXParserFactory saxparserfactory = SAXParserFactory.newInstance();
				//2、解析器
				SAXParser Sparser = saxparserfactory.newSAXParser();
				//3、get xmlreader,得到读取器
				XMLReader xreader = Sparser.getXMLReader();
				
				//4、设置内容处理器;
				//ContentHandler handler = xreader.getContentHandler();     获取处理器,但处理器的函数都是void类型,返回不了信息,则需要复写内部方法
				//(1)实现接口 ContentHandler
				//xreader.setContentHandler(new ListHandler1());   //实现ContentHandler,创建对象传入
				//(2)继承类 DefaultHandler
				xreader.setContentHandler(new ListHandler2());
				//5、读取xml文档的内容
				xreader.parse(new InputSource("src/cn/itcast/xml/dom1.xml"));
	}

}


//(1)写好了一个处理器,得到xml文档所有内容
class ListHandler1 implements ContentHandler
{
	
	private String currentTag;
	@Override
	public void setDocumentLocator(Locator locator) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void startDocument() throws SAXException {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void endDocument() throws SAXException {
		// TODO Auto-generated method stub
		
	}

	@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 {
		
		currentTag = qName;
		
	}

	@Override
	public void endElement(String uri, String localName, String qName)
			throws SAXException {
	        currentElement = null;  //置空方便下个标签的读取	
		
	}

	@Override
	public void characters(char[] ch, int start, int length)
			throws SAXException {
		// TODO Auto-generated method stub
		//解析获得标签的内容
		if (currentTag.equals("售价"))
		{
			System.out.println(currentTag);
			System.out.println("售价是:"+new String(ch,start,length)+"len="+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
		
	}
	
}

//(2)继承类,复写3个方法即可
class ListHandler2 extends DefaultHandler
{
	private String currentElement;
	@Override
	public void startElement(String uri, String localName, String qName,
			Attributes attributes) throws SAXException {
		currentElement = qName;
	}

	@Override
	public void endElement(String uri, String localName, String qName)
			throws SAXException {
		
	}

	@Override
	public void characters(char[] ch, int start, int length)
			throws SAXException {
		if ("作者".equals(currentElement))
		{
			System.out.println(new String(ch,start,length));
		}
		
	}
	
	
}