1. 程式人生 > >Java解析xml——SAX解析

Java解析xml——SAX解析

一、Dom解析 VS SAX解析

Dom解析是將整個xml檔案載入到記憶體中,然後再進行相關的操作。

SAX解析是依次讀取xml檔案的內容,逐個解析。


二、SAX解析例項

books.xml:

<?xml version="1.0" encoding="UTF-8"?>
<bookstore>
	<book id="1">
		<name>冰與火之歌</name>
		<author>喬治馬丁</author>
		<time>2014</time>
		<price>89</price>
	</book>
	<book id="2">
		<name>安徒生童話</name>
		<price>40</price>
		<time>2004</time>
		<language>English</language>
	</book>
</bookstore>

SaxDemo.java

public class SaxDemo {

	public static void main(String[] args) {
		//1、建立SAXParserFactory例項
		SAXParserFactory factory = SAXParserFactory.newInstance();
		try {
			//2、建立SAXParser例項
			SAXParser parser = factory.newSAXParser();
			//3、新建一個類SAXHandler繼承DefaultHandler,重寫其中的一些方法用來進行業務處理。
			//再建立一個SAXHandler物件
			SAXHandler handler = new SAXHandler();
			//4、進行解析,傳入SAXHandler物件作為解析xml的處理類
			parser.parse("xml/books.xml", handler);
			
		} catch (ParserConfigurationException e) {
			e.printStackTrace();
		} catch (SAXException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}
SAXHandler.java
public class SAXHandler extends DefaultHandler {

	int bookIndex = 0;
	
	/**
	 * 開始解析xml檔案
	 */
	@Override
	public void startDocument() throws SAXException {
		super.startDocument();
		
		System.out.println("開始解析xml檔案");
	}
	
	/**
	 * 解析xml檔案結束
	 */
	@Override
	public void endDocument() throws SAXException {
		super.endDocument();
		
		System.out.println("解析xml檔案結束");
	}
	
	/**
	 * 開始解析xml元素
	 */
	@Override
	public void startElement(String uri, String localName, String qName,
			Attributes attributes) throws SAXException {
		super.startElement(uri, localName, qName, attributes);
		
		//qName為標籤名稱
		if("book".equals(qName)) {
			bookIndex++;
			System.out.println("======開始解析第" + bookIndex + "本書======");
			//如果已知標籤的屬性,則可以直接呼叫Attributes.getValue(String name)獲取屬性值
			System.out.println("已知book已有id屬性,獲取屬性值-->" + attributes.getValue("id"));
			
			//如果不知道標籤的屬性,則需要遍歷Attributes分別獲取屬性名與屬性值
			int len = attributes.getLength();
			System.out.println("book元素有" + len + "個屬性");
			for(int i = 0; i < len; i++) {
				//通過Attributes.getQName(int index)獲取屬性名稱
				System.out.print("獲取book屬性" + attributes.getQName(i));
				//通過Attributes.getValue(int index)獲取屬性值
				System.out.println(",屬性值-->" + attributes.getValue(i));
			}
		} else if(!"books".equals(qName) && !"bookstore".equals(qName)) {
			System.out.print("解析到節點" + qName);
		}
	}
	
	/**
	 * 解析xml元素結束
	 */
	@Override
	public void endElement(String uri, String localName, String qName) throws SAXException {
		super.endElement(uri, localName, qName);
		
		if("book".equals(qName)) {
			System.out.println("======解析第" + bookIndex + "本書結束======");
		}
	}
	
	@Override
	public void characters(char[] ch, int start, int length) throws SAXException {
		super.characters(ch, start, length);
		//ch為整個xml文件的內容,start為當前標籤內容所在位置,length為當前標籤內容的長度
		//需要過濾掉空格和換行,SAX解析也會把空格和換行當做xml文件的內容
		String str = new String(ch, start, length);
		if(!"".equals(str.trim())) {
			System.out.println("-->節點值:" + str);
		}
	}
	
}

執行結果:

開始解析xml檔案
======開始解析第1本書======
已知book已有id屬性,獲取屬性值-->1
book元素有1個屬性
獲取book屬性id,屬性值-->1
解析到節點name-->節點值:冰與火之歌
解析到節點author-->節點值:喬治馬丁
解析到節點time-->節點值:2014
解析到節點price-->節點值:89
======解析第1本書結束======
======開始解析第2本書======
已知book已有id屬性,獲取屬性值-->2
book元素有1個屬性
獲取book屬性id,屬性值-->2
解析到節點name-->節點值:安徒生童話
解析到節點price-->節點值:40
解析到節點time-->節點值:2004
解析到節點language-->節點值:English
======解析第2本書結束======
解析xml檔案結束

從執行結果可以看出SAX解析Handler處理順序是:xml檔案開頭的startDocument-->所有節點startElement-->characters-->endElement-->檔案末尾endDocument