(六)使用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. }  


 

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