1. 程式人生 > >Java使用Sax解析xml檔案

Java使用Sax解析xml檔案

使用java的Sax對xml檔案進行解析,大致可分為以下幾個步驟

1、建立SAXParserFactory例項

2、建立SAXParser例項

3、建立一個繼承自DefaultHandler的handler例項

4、使用handler對xml文件進行解析

一、要解析的book.xml文件如下

<?xml version="1.0" encoding="UTF-8"?>
<bookstore>
	<book id="156">
		<name>計算機網路</name>
		<author>謝希仁</author>
		<price>39</price>
		<year>2013</year>
	</book>
	<book id="234">
		<name>計算機作業系統</name>
		<author>佚名</author>
		<price>40</price>
		<year>2013</year>
		<edition>第四版</edition>
	</book>
	<book id="367">
		<name>計算機組成原理</name>
		<price>35</price>
		<year>2013</year>
		<edition>第三版</edition>
	</book>
</bookstore>
二、建立SAXParserFactory例項
// 建立SAXParserFactory例項
SAXParserFactory spf = SAXParserFactory.newInstance();


三、建立SAXParser例項
// 建立SAXParser例項
SAXParser parser = spf.newSAXParser();

四、建立DefaultHandler例項(這一步是非常關鍵的一步)

DefaultHandler有如下幾個介面

 一般前兩個方法,開始解析和結束解析文件的不需要做處理外,我們的所有操作都是在解析節點部分,我們呼叫startElement 開始解析節點,然後呼叫characters 儲存節點的內容,最後呼叫endElement表示結束對一個節點的訪問


        public void startDocument() {
		// 開始解析文件
	}

	public void endDocument() {
		// 文件解析結束
	}

	public void startElement(String uri, String localName, String qName, Attributes attributes) {
		// 開始解析元素節點,注意,此處只是會解析元素節點,即 XML 標籤,遇到回車等textNode時不會執行此函式
	}

	public void characters(char[] ch, int start, int length) {
		// 儲存節點內容,此處會將回車等textNode的回車符也進行解析
	}

	public void endElement(String uri, String localName, String qName) {
		// 結束解析元素節點
	}



下面是一個解析book.xml的Handler

public class MyHandler extends DefaultHandler {
	int bookIndex = 0;

	/**
	 * 用來遍歷開始標籤,每走到一個開始標籤,如<div>,<book>等不帶/的標籤,就會呼叫一次該方法
	 * 
	 * @param uri
	 * @param localName
	 * @param qName
	 *            節點名,即標籤名稱
	 * @param attributes
	 *            標籤的屬性
	 */
	@Override
	public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
		// 呼叫DefaultHandler類的startElement方法
		super.startElement(uri, localName, qName, attributes);
		// 如果是book開始節點
		if ("book".equals(qName)) {
			bookIndex++;
			// 獲取id屬性值
			String id = attributes.getValue("id");
			System.out.println("id是:" + id);
		}
		// 如果是book節點下的子節點的開始節點
		else if (!"bookstore".equals(qName)) {
			System.out.print(qName + ":");
		}
	}

	/**
	 * 儲存元素節點中的文字節點的文字內容
	 * 
	 * @param ch
	 *            節點中的內容
	 * @param start
	 *            開始標籤的位置
	 * @param length
	 *            開始標籤的位置到結束標籤的位置的長度
	 */
	@Override
	public void characters(char[] ch, int start, int length) throws SAXException {
		super.characters(ch, start, length);
		String value = new String(ch, start, length);
		// 如果節點內容不為空,主要是用來過濾回車符形成的textNode
		if (!value.trim().equals("")) {
			System.out.println(value);
		}
	}

	/**
	 * 用來遍歷結束標籤
	 */
	@Override
	public void endElement(String uri, String localName, String qName) throws SAXException {
		super.endElement(uri, localName, qName);
		// 如果是book節點結束
		if ("book".equals(qName)) {
			System.out.println("--------------結束遍歷第" + bookIndex + "本書---------------");
		}

	}

	/**
	 * 用來標識解析開始
	 */
	@Override
	public void startDocument() throws SAXException {
		super.startDocument();
		System.out.println("開始解析xml檔案");
	}

	/**
	 * 用來標識解析結束
	 */
	@Override
	public void endDocument() throws SAXException {
		super.endDocument();
		System.out.println("結束解析xml檔案");
	}

}

五、使用handler對xml文件進行解析

// 開始解析
parser.parse("book.xml", new MyHandler());


六、執行結果

執行結果如下:

<span style="font-family: Tahoma, Verdana, Geneva, Arial, Helvetica, sans-serif;">開始解析xml檔案
id是:156
name:計算機網路
author:謝希仁
price:39
year:2013
--------------結束遍歷第1本書---------------
id是:234
name:計算機作業系統
author:佚名
price:40
year:2013
edition:第四版
--------------結束遍歷第2本書---------------
id是:367
name:計算機組成原理
price:35
year:2013
edition:第三版
--------------結束遍歷第3本書---------------
結束解析xml檔案</span>

在重寫DefaultHandler的startElement,characters介面時需注意一下細節

1、當遇到一個開始元素節點時就會執行一次startElement,這裡需要特別注意,元素節點指的是一個xml標籤,也就是說遇到開始文字節點不會執行該方法

下面我們把節點名都打印出來,發現的確只是打印出了xml標籤,即元素節點。而並沒有#text型別的文字節點

	@Override
	public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
		// 呼叫DefaultHandler類的startElement方法
		super.startElement(uri, localName, qName, attributes);
		System.out.println(qName);

	}

列印結果如下:

開始解析xml檔案
bookstore
book
name
author
price
year
book
name
author
price
year
edition
book
name
price
year
edition
結束解析xml檔案

2、當遇到空格或者換行符時,也會觸發characters方法。