在java中使用sax解析xml


在java中,原生解析xml文檔的方式有兩種,分別是:Dom解析和Sax解析

Dom解析功能強大,可增刪改查,操作時會將xml文檔以文檔對象的方式讀取到內存中,因此適用於小文檔

Sax解析是從頭到尾逐行逐個元素讀取內容,修改較為不便,但適用於只讀的大文檔

本文主要講解Sax解析,其余放在后面

 

Sax采用事件驅動的方式解析文檔。簡單點說,如同在電影院看電影一樣,從頭到尾看一遍就完了,不能回退(Dom可來來回回讀取)

在看電影的過程中,每遇到一個情節,一段淚水,一次擦肩,你都會調動大腦和神經去接收或處理這些信息

同樣,在Sax的解析過程中,讀取到文檔開頭、結尾,元素的開頭和結尾都會觸發一些回調方法,你可以在這些回調方法中進行相應事件處理

這四個方法是:startDocument() 、 endDocument()、 startElement()、 endElement

此外,光讀取到節點處是不夠的,我們還需要characters()方法來仔細處理元素內包含的內容

將這些回調方法集合起來,便形成了一個類,這個類也就是我們需要的觸發器

一般從Main方法中讀取文檔,卻在觸發器中處理文檔,這就是所謂的事件驅動解析方法

如上圖,在觸發器中,首先開始讀取文檔,然后開始逐個解析元素,每個元素中的內容會返回到characters()方法

接着結束元素讀取,所有元素讀取完后,結束文檔解析

 

現在我們開始創建觸發器這個類,要創建這個類首先需要繼承DefaultHandler

創建SaxHandler,並覆寫相應方法:

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


public class SaxHandler extends DefaultHandler {

	/* 此方法有三個參數
	   arg0是傳回來的字符數組,其包含元素內容
	   arg1和arg2分別是數組的開始位置和結束位置 */
	@Override
	public void characters(char[] arg0, int arg1, int arg2) throws SAXException {
		String content = new String(arg0, arg1, arg2);
		System.out.println(content);
		super.characters(arg0, arg1, arg2);
	}

	@Override
	public void endDocument() throws SAXException {
		System.out.println("\n…………結束解析文檔…………");
		super.endDocument();
	}

	/* arg0是名稱空間
	   arg1是包含名稱空間的標簽,如果沒有名稱空間,則為空
	   arg2是不包含名稱空間的標簽 */
	@Override
	public void endElement(String arg0, String arg1, String arg2)
			throws SAXException {
		System.out.println("結束解析元素  " + arg2);
		super.endElement(arg0, arg1, arg2);
	}

	@Override
	public void startDocument() throws SAXException {
		System.out.println("…………開始解析文檔…………\n");
		super.startDocument();
	}

	/*arg0是名稱空間
	  arg1是包含名稱空間的標簽,如果沒有名稱空間,則為空
	  arg2是不包含名稱空間的標簽
	  arg3很明顯是屬性的集合 */
	@Override
	public void startElement(String arg0, String arg1, String arg2,
			Attributes arg3) throws SAXException {
		System.out.println("開始解析元素 " + arg2);
		if (arg3 != null) {
			for (int i = 0; i < arg3.getLength(); i++) {
				 // getQName()是獲取屬性名稱,
				System.out.print(arg3.getQName(i) + "=\"" + arg3.getValue(i) + "\"");
			}
		}
		System.out.print(arg2 + ":");
		super.startElement(arg0, arg1, arg2, arg3);
	}
}

XML文檔:

<?xml version="1.0" encoding="UTF-8"?> 
<books> 
   <book id="001"> 
      <title>Harry Potter</title> 
      <author>J K. Rowling</author> 
   </book> 
   <book id="002"> 
      <title>Learning XML</title> 
      <author>Erik T. Ray</author> 
   </book> 
</books> 

 TestDemo測試類:

import java.io.File;

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


public class TestDemo {

	public static void main(String[] args) throws Exception {
		// 1.實例化SAXParserFactory對象
		SAXParserFactory factory = SAXParserFactory.newInstance();
		// 2.創建解析器
		SAXParser parser = factory.newSAXParser();
		// 3.獲取需要解析的文檔,生成解析器,最后解析文檔
		File f = new File("books.xml");
		SaxHandler dh = new SaxHandler();
		parser.parse(f, dh);
	}
}

 輸出結果:

…………開始解析文檔…………

開始解析元素 books
books: 
   
開始解析元素 book
id="001"book: 
      
開始解析元素 title
title:Harry Potter
結束解析元素  title
 
      
開始解析元素 author
author:J K. Rowling
結束解析元素  author
 
   
結束解析元素  book
 
   
開始解析元素 book
id="002"book: 
      
開始解析元素 title
title:Learning XML
結束解析元素  title
 
      
開始解析元素 author
author:Erik T. Ray
結束解析元素  author
 
   
結束解析元素  book
 

結束解析元素  books

…………結束解析文檔…………

 

上面的雖然正確顯示了執行流程,但是輸出卻很亂

為了更加清晰的執行此流程,我們還可以重寫SaxHandler,使其將原先的xml文檔還原一遍

重寫的SaxHandler類:

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


public class SaxHandler extends DefaultHandler {

	@Override
	public void characters(char[] arg0, int arg1, int arg2) throws SAXException {
		System.out.print(new String(arg0, arg1, arg2));
		super.characters(arg0, arg1, arg2);
	}

	@Override
	public void endDocument() throws SAXException {
		System.out.println("\n結束解析");
		super.endDocument();
	}

	@Override
	public void endElement(String arg0, String arg1, String arg2)
			throws SAXException {
		System.out.print("</");
		System.out.print(arg2);
		System.out.print(">");
		super.endElement(arg0, arg1, arg2);
	}

	@Override
	public void startDocument() throws SAXException {
		System.out.println("開始解析");
		String s = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>";
		System.out.println(s);
		super.startDocument();
	}

	@Override
	public void startElement(String arg0, String arg1, String arg2,
			Attributes arg3) throws SAXException {
		
		System.out.print("<");
		System.out.print(arg2);
		
		if (arg3 != null) {
			for (int i = 0; i < arg3.getLength(); i++) {
				System.out.print(" " + arg3.getQName(i) + "=\"" + arg3.getValue(i) + "\"");
			}
		}
		System.out.print(">");
		super.startElement(arg0, arg1, arg2, arg3);
	}

}

 執行結果:

現在看起來好多了,將其還原更能充分說明其解析流程

 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM