Java眼中的XML---檔案讀取(二)SAX解析XML檔案
阿新 • • 發佈:2018-12-27
目錄
(一)SAX解析是什麼?
SAX(simple API for XML)是一種XML解析的替代方法。相比於DOM,SAX是一種速度更快,更有效的方法。它逐行掃描文件,一邊掃描一邊解析。而且相比於DOM,SAX可以在解析文件的任意時刻停止解析,但任何事物都有其相反的一面,對於SAX來說就是操作複雜。
(二)SAX解析和DOM解析的區別?
DOM解析 | SAX解析 |
---|---|
一次性載入xml文件,不適合大容量的檔案讀取 | 載入一點,讀取一點,處理一點。適合大容量檔案的讀取 |
DOM解析任意讀取任何位置的資料,甚至往回讀 | SAX解析只能從上往下,按順序讀取,不能往回讀 |
DOM解析可以任意進行增刪改查 | SAX解析只能讀取 |
DOM解析面向物件的程式設計方法(Node,Element,Attribute),Java開發者編碼比較簡單。 | SAX解析基於事件的程式設計方法。java開發編碼相對複雜。 |
(三)SAX方法解析XML的步驟
- 通過SAXParserFactory的靜態newInstence()方法 獲取SAXParserFactory例項factory
- 通過SAXParserFactory例項的newSAXParser()方法 返回SAXParser例項parser
- 建立一個類繼承DefaultHandler,重寫其中的一些方法進行業務處理並建立這個類的例項handler
- 將xml檔案地址和handler例項載入到SAXParser例項:parser.parse(“books.xml”,handler);
注:SAX解析的時候,其過程是:startElement-characters-endElement ; characters解析完一個屬性,到endElement結束,然後又開始解析下一個屬性,到endElement結束,以此類推,最後解析完全部屬性,又回到startElement開始解析下一個節點。
(四)SAX解析Java程式碼實現
1.測試主程式:
import java.io.IOException;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import org.xml.sax.SAXException;
import com.zzh.handle.SAXParserHandler;
public class test {
public static void main(String[] args) {
//獲取一個SAXParserFactory例項
SAXParserFactory factory = SAXParserFactory.newInstance();
try {
//通過factory物件獲取一個SAXParser例項
SAXParser parser = factory.newSAXParser();
//建立SAXParserHandle物件
SAXParserHandler handler = new SAXParserHandler();
parser.parse("books.xml", handler);
} catch (ParserConfigurationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SAXException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
2.SAXParserHandler類:
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
public class SAXParserHandler extends DefaultHandler {
int bookIndex = 0; //book節點索引值
/**
* 用來遍歷xml檔案的開始標籤
*/
@Override
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
// TODO Auto-generated method stub
super.startElement(uri, localName, qName, attributes);
if ("book".equals(qName)){
bookIndex ++;
System.out.println("======開始遍歷第" + bookIndex + "本書的內容======");
//已知book元素下屬性的名稱,根據屬性名稱獲取屬性值
// String value = attributes.getValue("id");
// System.out.println("book的屬性值是:" + value);
//不知道book元素下屬性的名稱,如何獲取屬性名以及屬性值
int num = attributes.getLength();
for(int i=0;i<num;i++){
System.out.print("book元素的第" + (i + 1) + "個屬性名是:"
+attributes.getQName(i));
System.out.println("---屬性值是:" + attributes.getQName(i));
}
}else if(!"book".equals(qName) && !"bookstore".equals(qName)){
System.out.print("節點名是:" + qName);
}
}
/**
* 用來遍歷xml檔案的結束標籤
*/
@Override
public void endElement(String uri, String localName, String qName) throws SAXException {
// TODO Auto-generated method stub
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 {
// TODO Auto-generated method stub
super.characters(ch, start, length);
String value = new String(ch,start,length);
//除去Text型別的節點
if(!"".equals(value.trim())){
System.out.println("---節點值是:" + value);
}
}
/**
* 用來標識標誌解析開始
*/
@Override
public void startDocument() throws SAXException {
// TODO Auto-generated method stub
super.startDocument();
System.out.println("====SAX解析開始====");
}
/**
* 用來標識標誌解析結束
*/
@Override
public void endDocument() throws SAXException {
// TODO Auto-generated method stub
super.endDocument();
System.out.println("====SAX解析結束====");
}
}
3.程式執行結果展示:
4.books.xml檔案原始碼:
<?xml version="1.0" encoding="UTF-8"?>
<bookstore>
<book id="1">
<name>冰與火之歌</name>
<author>喬治馬丁</author>
<year>2014</year>
<price>88</price>
</book>
<book id="2">
<name>安徒生童話</name>
<year>2004</year>
<price>77</price>
<language>English</language>
</book>
</bookstore>