XML是一種通用的資料交換格式,它的平台無關,語言無關,系統無關,在不同的語言環境的解析方式都是一樣的,隻不過是實作的文法不同。
DOM ,SAX屬于基礎方法,是官方提供的平台無關的解析方式;JDOM,DOM4J屬于擴充方法,他們是在基礎的方法上擴充出來,隻适用于Java平台;
JAXP是SDK提供的一套解析XML的API,支援DOM和SAX解析方式,JAXP是JavaSE一部分,它由javax.xml,org.w3c.sax,org.xml.sax包及其子包組成。從JDK6.0開始,JAXP開始支援另一種XML解析方式--StAX解析方式。
本文将重點介紹下用SAX解析檔案:
SAX解析方式會逐行地去掃描XML文檔,當遇到标簽時會觸發解析處理器,采用事件處理的方式解析XML (Simple API for XML) ,不是官方标準,但它是 XML 社群事實上的标準,幾乎所有的 XML 解析器都支援它。
優點是:在讀取文檔的同時即可對XML進行處理,不必等到文檔加載結束,相對快捷。不需要加載進記憶體,是以不存在占用記憶體的問題,可以解析超大XML。
缺點是:隻能用來讀取XML中資料,無法進行增删改。
![](https://img.laitimes.com/img/_0nNw4CM6IyYiwiM6ICdiwiI0gTMx81dsQWZ4lmZf1GLlpXazVmcvwFciV2dsQXYtJ3bm9CX9s2RkBnVHFmb1clWvB3MaVnRtp1XlBXe0xCMy81dvRWYoNHLwEzX5xCMx8FesU2cfdGLwMzX0xiRGZkRGZ0Xy9GbvNGLpZTY1EmMZVDUSFTU4VFRR9Fd4VGdsYTMfVmepNHLrJXYtJXZ0F2dvwVZnFWbp1zczV2YvJHctM3cv1Ce-cmbw5SN1UDN0ADMkZGOkhjYkRGOyYzX5IjMzUTM1IzLcVDMyIDMy8CXn9Gbi9CXzV2Zh1WavwVbvNmLvR3YxUjLyM3Lc9CX6MHc0RHaiojIsJye.png)
SAX解析可分四個步驟進行:
1、得到xml檔案對應的資源,可以是xml的輸入流,檔案和uri
2、得到SAX解析工廠(SAXParserFactory)
3、由解析工廠生産一個SAX解析器(SAXParser)
4、傳入輸入流和handler給解析器,調用parse()解析
public static void main(String[] args) throws Exception {
//1.建立解析工廠
SAXParserFactoryfactory=SAXParserFactory.newInstance();
//2.得到解析器
SAXParser sp=factory.newSAXParser();
//3得到解讀器
XMLReader reader=sp.getXMLReader();
//設定内容處理器
reader.setContentHandler(new ListHandler());
//讀取xml的文檔内容
reader.parse("src/Book.xml");
}
}
1.建立一個Book.xml的 xml文檔
<?xml version="1.0" encoding="UTF-8"?>
<書架>
<書>
<書名 name="dddd">java web就業</書名>
<作者>張三</作者>
<售價>40</售價>
</書>
<書>
<書名 name="xxxx">HTML教程</書名>
<作者>自己</作者>
<售價>50</售價>
</書>
</書架>
View Code
2.建立一個javaBean實體類
package sax;
public class Book {
private String name;
private String author;
private String price;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
public String getPrice() {
return price;
}
public void setPrice(String price) {
this.price = price;
}
@Override
public String toString() {
return "Book [name=" + name + ", author=" + author + ", price=" + price + "]";
}
}
View Code
3.建立一個ListHandler類,這個類需要DefaultHandler或者實作ContentHandler接口。該類是SAX解析的核心所在,我們要重寫以下幾個我們關心的方法。
1、startDocument():文檔解析開始時調用,該方法隻會調用一次
2、startElement(String uri, String localName, String qName,
3、Attributes attributes):标簽(節點)解析開始時調用
uri:xml文檔的命名空間
localName:标簽的名字
qName:帶命名空間的标簽的名字
attributes:标簽的屬性集
characters(char[] ch, int start, int length):解析标簽的内容的時候調用
ch:目前讀取到的TextNode(文本節點)的位元組數組
start:位元組開始的位置,為0則讀取全部
length:目前TextNode的長度
4、endElement(String uri, String localName, String qName):标簽(節點)解析結束後調用
5、endDocument():文檔解析結束後調用,該方法隻會調用一次
建立的ListHandler類實作完整代碼如下:
class ListHandler implements ContentHandler{
/**
* 當讀取到第一個元素時開始做什麼
*/
@Override
public void startElement(String uri, String localName, String qName,
Attributes atts) throws SAXException {
System.out.print("<"+qName);
for(int i=0;atts!=null&&i<atts.getLength();i++){
String attName=atts.getQName(i);
String attValueString=atts.getValue(i);
System.out.print(" "+attName+"="+attValueString);
System.out.print(">");
}
}
/**
* 表示讀取到第一個元素結尾時做什麼
*/
@Override
public void endElement(String uri, String localName, String qName)
throws SAXException {
System.out.print("</"+qName+">");
}
/**
* 表示讀取字元串時做什麼
*/
@Override
public void characters(char[] ch, int start, int length)
throws SAXException {
System.out.print(new String(ch,start,length));
}
@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 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
}
}
View Code
到此,sax方式解析XML文檔結束。
總結,SAX解析XML具有解析速度快,占用記憶體少,對于Android等移動裝置來說有巨大的優勢,深入了解SAX的事件觸發機制是掌握SAX解析的關鍵,掌握了SAX的事件觸發就掌握了SAX解析XML
運作結果圖: