天天看點

使用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));
		}
		
	}
	
	
}