1. 程式人生 > >XML解析之SAX方式解析xml檔案

XML解析之SAX方式解析xml檔案

SAX解析方式會逐行地去掃描XML文件,當遇到標籤時會觸發解析處理器,採用事件處理的方式解析XML (Simple API for XML) ,不是官方標準,但它是 XML 社群事實上的標準,幾乎所有的 XML 解析器都支援它。優點是:在讀取文件的同時即可對XML進行處理,不必等到文件載入結束,相對快捷。不需要載入進記憶體,因此不存在佔用記憶體的問題,可以解析超大XML。缺點是:只能用來讀取XML中資料,無法進行增刪改。
SAX解析原理圖
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</售價> </> </書架>

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 + "]";
    }
}

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

    }

}

到此,sax方式解析XML文件結束。
總結,SAX解析XML具有解析速度快,佔用記憶體少,對於Android等移動裝置來說有巨大的優勢,深入瞭解SAX的事件觸發機制是掌握SAX解析的關鍵,掌握了SAX的事件觸發就掌握了SAX解析XML,附上執行結果圖!本文如有理解不當之處,還請各位指出,並共勉!
sax解析xml文件效果圖