1. 程式人生 > >XML解析之——SAX解析

XML解析之——SAX解析

一、定義

SAX,全稱 Simple API for XML,是一種以事件驅動的XML API 由於它是邊掃描邊解析,所以具有解析速度快、佔用記憶體小的有點。

二、解析步驟

1、獲取XML檔案資源,可以是XML檔案的輸入流或者檔案、uri。

2、得到SAX解析器工廠(SAXParserFactory)。

SAXParserFactory factory= SAXParserFactory.newInstance();

3、通過SAX解析器工廠獲取SAX解析器(SAXParser)。

SAXParser parser=factory.newSAXParser();

4、重寫SAXParser解析所需要的DefaultHandler類,在此類中進行具體的XML檔案解析操作。

5、最後呼叫SAXParser的parse()方法,開始解析。

parser.parser(inputStream,myDefaultHandler);

三、DefaultHanler的五個方法

SAXParser解析器在呼叫parse()方法時,需要提供兩個引數,第一個是XML檔案資源,可以是輸入流(InputStream)、檔案(File)、uri(String)。第二個是一個需要繼承DefaultHandler的物件例項。通常需要重寫這個類的五個方法以達到解析XML的目的。

1、public void startDocument() 

解析開始時呼叫此方法,一般在此方法中建立一個XML元素的List集合。

2、 public void startElement(String uri, String localName, String qName, Attributes attributes)

當parser解析到一個開始標籤時,呼叫此方法,在此方法中進行標籤名稱的判斷。

namespaceURI——名稱空間

localName——標籤名稱

fullName——帶名稱空間的標籤名

Attributes——存放該標籤的所有屬性

3、 public void characters(char[] ch, int start, int length) 

在此方法中進行標籤內容的獲取。char[]陣列存放了對應標籤的值。

4、 public void endElement(String uri, String localName, String qName)

在此方法中判斷結束標籤名稱是否為整個XML元素的結束標籤,如果是則把此元素新增到之前建立的list集合中。

5、 public void endDocument()

四、應用例項

1、建立一個SaxParse類,進行SAX解析操作。

package com.example.pc.xmlparsetest;

import android.widget.TextView;

import org.w3c.dom.Text;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

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

/**
 * Created by pc on 2018/6/3.
 */

public class SaxParse {

    private SAXParserFactory factory;
    private InputStream is;
    private List<Movie> movies=new ArrayList<Movie>();
    private TextView showMovies;

    public SaxParse(SAXParserFactory factory,InputStream is,TextView showMovies) {
        this.factory = factory;
        this.is=is;
        this.showMovies=showMovies;
    }


    public void parse() throws ParserConfigurationException, SAXException, IOException {
        //通過SAXParser解析工廠獲取SAXParser例項
        SAXParser parser=factory.newSAXParser();
        //建立重寫的MyDfaultHandler類
        MyDefaultHandler handler=new MyDefaultHandler();
        //開始解析
        parser.parse(is,handler);
        //獲取解析得到的list集合
        movies=handler.getResult();
        showMovies.setText(movies.toString());
        is.close();

    }
}

2、建立重寫的DefaultHandler類。

package com.example.pc.xmlparsetest;

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

import java.util.ArrayList;
import java.util.List;

/**
 * Created by pc on 2018/6/3.
 */

public class MyDefaultHandler extends DefaultHandler {
    private List<Movie> movies;
    private String elementTag;
    private Movie m;


    @Override
    public void startDocument() throws SAXException {
        super.startDocument();
        //建立儲存所有Movie元素的的集合
        movies=new ArrayList<Movie>();
    }

    @Override
    public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
       //如果開始標籤名稱為movie則建立一個Movie物件
       if("movie".equals(qName)){

          m=new Movie();


       }
       //將標籤名稱儲存
        elementTag=qName;
        super.startElement(uri, localName, qName, attributes);
    }

    @Override
    public void characters(char[] ch, int start, int length) throws SAXException {
         //獲得對應標籤的內容
        String content=new String(ch,start,length);
        //判斷標籤名稱,並將對應值存入之前建立的Movie物件中
        if("name".equals(elementTag)){
             m.setName(content);
        }else if("director".equals(elementTag)){
            m.setDirector(content);
        }else if("country".equals(elementTag)){
            m.setCountry(content);
        }

        super.characters(ch, start, length);

    }

    @Override
    public void endElement(String uri, String localName, String qName) throws SAXException {

        elementTag="";
        //如果結束標籤時movie則將建立的Movie物件新增到集合中
        if(qName.equals("movie")){

            movies.add(m);
        }
        super.endElement(uri, localName, qName);

    }

    @Override
    public void endDocument() throws SAXException {
        super.endDocument();
    }
    //返回結果list集合
    public List<Movie> getResult(){

        return movies;

    }
}

3、在Activity中建立SaxParser物件,並呼叫他的parse類進行解析。

                  //建立儲存在Assets資料夾中的XML輸入流
                  AssetManager am2=getAssets();
                  try {
                      is2=am2.open("movies.xml");

                  } catch (IOException e) {
                      e.printStackTrace();
                  }
                  //建立解析類,並傳入引數
                  SaxParse sp=new SaxParse(factory,is2,showMovies);
                  try {
                      //開始解析
                      sp.parse();
                  } catch (ParserConfigurationException e) {
                      e.printStackTrace();
                  } catch (SAXException e) {
                      e.printStackTrace();
                  } catch (IOException e) {
                      e.printStackTrace();
                  }

4、執行結果