(六)使用SAX解析xml文檔

SAX的全稱是Simple APIs for XML,也即XML簡單應用程序接口。

使用DOM解析XML時,首先將XML文檔加載到內存當中,然後可以通過隨機的方式訪問內存中的DOM樹;SAX是基於事件而且是順序執行的,一旦經過了某個元素,我們就沒有辦法再去訪問他了,SAX不必事先將整個XML文檔加載到內存中,因此它佔據內存要比DOM小,對於大型的XML文檔來說,通常會使用SAX而不是DOM進行解析。

SAX提供的訪問模式是一種順序模式,這是一種快速讀寫XML數據的方式。當使用SAX分析器對XML文檔進行分析時,會觸發一系列事件,並激活相應的事件處理函數,應用程序通過這些事件處理函數實現對XML文檔的訪問,因而SAX接口也被稱作事件驅動接口。
SAX分析器在對XML文檔進行分析時,觸發了一系列的事件,由於事件觸發本身是有時序性的,因此,SAX提供的是一種順序訪問機制,對於已經分析過的部分,不能再倒回去重新處理。SAX之所以被叫做"簡單"應用程序接口,是因爲SAX分析器只做了一些簡單的工作,大部分工作還要由應用程序自己去做。也就是說,SAX分析器在實現時,它只是順序地檢查XML文檔中的字節流,判斷當前字節是XML語法中的哪一部分、是否符合XML語法,然後再觸發相應的事件,而事件處理函數本身則要由應用程序自己來實現。同DOM分析器相比,SAX分析器缺乏靈活性。然而,由於SAX分析器實現簡單,對內存要求比較低,因此實現效率比較高,對於那些只需要訪問XML文檔中的數據而不對文檔進行更改的應用程序來說,SAX分析器更爲合適。

SAX使用觀察者模式

1、SAX分析器的大體構成框架

圖中最上方的SAXParserFactory用來生成一個分析器實例。XML文檔是從左側箭頭所示處讀入,當分析器對文檔進行分析時,就會觸發在DocumentHandler,ErrorHandler,DTDHandler以及EntityResolver接口中定義的回調方法。
•SAX是事件驅動的,文檔的讀入過程就是SAX的解析過程。
•在讀入的過程中,遇到不同的項目,解析器會調用不同的處理方法。

2、工廠及解釋器的使用同DOM

SAXParserFactory、SAXParser

[java] view plain copy
  1. import java.io.File;  
  2.   
  3. import javax.xml.parsers.SAXParser;  
  4. import javax.xml.parsers.SAXParserFactory;  
  5.   
  6. import org.xml.sax.Attributes;  
  7. import org.xml.sax.SAXException;  
  8. import org.xml.sax.helpers.DefaultHandler;  
  9.   
  10. public class SaxTest  
  11. {  
  12.     public static void main(String[] args) throws Exception, SAXException  
  13.     {  
  14.         //step1:獲得SAX解析器工廠實例  
  15.         SAXParserFactory factory = SAXParserFactory.newInstance();  
  16.           
  17.         //step2:獲得SAX解析器實例  
  18.         SAXParser parser = factory.newSAXParser();  
  19.           
  20.         //step3:開始進行解析  
  21.         parser.parse(new File("student.xml"), new MyHandler());  
  22.     }  
  23. }  
  24.   
  25. class MyHandler extends DefaultHandler  
  26. {  
  27.     @Override  
  28.     public void startDocument() throws SAXException  
  29.     {  
  30.         System.out.println("parse began");  
  31.     }  
  32.     @Override  
  33.     public void endDocument() throws SAXException  
  34.     {  
  35.         System.out.println("parse end");  
  36.     }  
  37.       
  38.     @Override  
  39.     public void startElement(String uri, String localName, String qName,  
  40.             Attributes attributes) throws SAXException  
  41.     {  
  42.         System.out.println("start element");  
  43.     }  
  44.     @Override  
  45.     public void endElement(String uri, String localName, String qName)  
  46.             throws SAXException  
  47.     {  
  48.         System.out.println("finished element");  
  49.     }  
  50. }  


解析一個XML文檔,xml文檔內容:

[html] view plain copy
  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <學生名冊>  
  3.     <學生 學號="1">  
  4.         <姓名>張三</姓名>  
  5.         <性別></性別>  
  6.         <年齡>20</年齡>  
  7.     </學生>  
  8.     <學生 學號="2">  
  9.         <姓名>李四</姓名>  
  10.         <性別></性別>  
  11.         <年齡>19</年齡>  
  12.     </學生>  
  13.     <學生 學號="3">  
  14.         <姓名>王五</姓名>  
  15.         <性別></性別>  
  16.         <年齡>21</年齡>  
  17.     </學生>  
  18. </學生名冊>  


具體的解析程序:

[java] view plain copy
  1. import java.io.File;  
  2. import java.util.Stack;  
  3.   
  4. import javax.xml.parsers.ParserConfigurationException;  
  5. import javax.xml.parsers.SAXParser;  
  6. import javax.xml.parsers.SAXParserFactory;  
  7.   
  8. import org.xml.sax.Attributes;  
  9. import org.xml.sax.SAXException;  
  10. import org.xml.sax.helpers.DefaultHandler;  
  11.   
  12. public class SaxTest2  
  13. {  
  14.     public static void main(String[] args) throws Exception  
  15.     {  
  16.         SAXParserFactory factory =SAXParserFactory.newInstance();  
  17.         SAXParser parser = factory.newSAXParser();  
  18.         parser.parse(new File("student.xml"), new MyHandler2());  
  19.     }  
  20.       
  21. }  
  22.   
  23. class MyHandler2 extends DefaultHandler  
  24. {  
  25.     private Stack<String> stack = new Stack<String>();  
  26.     private String name;  
  27.     private String gender;  
  28.     private String age;  
  29.       
  30.     @Override  
  31.     public void startElement(String uri, String localName, String qName,  
  32.             Attributes attributes) throws SAXException  
  33.     {  
  34.         stack.push(qName);  
  35.         for(int i = 0;i<attributes.getLength();i++)  
  36.         {  
  37.             String attrName = attributes.getQName(i);  
  38.             String attrValue = attributes.getValue(i);  
  39.               
  40.             System.out.println(attrName + "=" + attrValue);  
  41.         }  
  42.     }  
  43.     @Override  
  44.     public void characters(char[] ch, int start, int length)  
  45.             throws SAXException  
  46.     {  
  47.         String tag = stack.peek();  
  48.         if("姓名".equals(tag))  
  49.         {  
  50.             name = new String(ch,start,length);  
  51.         }  
  52.         else if("性別".equals(tag))  
  53.         {  
  54.             gender = new String(ch,start,length);  
  55.         }  
  56.         else if("年齡".equals(tag))  
  57.         {  
  58.             age = new String(ch,start,length);  
  59.         }  
  60.     }  
  61.     @Override  
  62.     public void endElement(String uri, String localName, String qName)  
  63.             throws SAXException  
  64.     {  
  65.         stack.pop();//表示該元素已經解析完畢,需要從棧中彈出  
  66.         if("學生".equals(qName))  
  67.         {  
  68.             System.out.println("姓名:"+ name);  
  69.             System.out.println("性別" + gender);  
  70.             System.out.println("年齡" + age);  
  71.             System.out.println();  
  72.         }  
  73.     }  
  74. }  


 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章