zoukankan      html  css  js  c++  java
  • 浅谈SAX,PULL解析XML

          这些一直以来比较迷迷糊糊,今天翻阅网上翻阅了相关博文和书籍,大致整理了一下(还是相对比较浅的,以后有了新的理解之后在继续深入)

    例如:

    待解析文件Classmate.xml
    
     
    
    <class>
    
      <student>
    
          <id>1</id>
    
          <name>Qbin</name>
    
           <sex>male</sex>
    
      </student>
    
      <student>
    
         <id>2</id>
    
         <name>Qmm</name>
    
          <sex>female</sex>
    
      </student>
    
      <student>
    
         <id>3</id>
    
         <name>Cmy</name>
    
          <sex>male</sex>
    
      </student>
    
    </class>

    SAX解析方法:

     public class Main{
    
      .......
    
      parseXMLWithSAX(xmldata);
    
      //调用SAX解析方法
    
      .......
    
      private void parseXMLWithSAX(String xmldata){
    
        try{
    
          SAXParserFactory factory = SAXParserFactory.newInstance();
    
             SAXParser parser = factory.newSAXParser();  
    
          //获得SAX解析器对象
    
              XMLReader xmlReader = parser.getXMLReader();  
    
          //获得XMLReader对象
    
     
    
          ContentHandler handler = new ContentHandler();
    
          xmlReader.setContentHandler(handler);
    
          //将handler模版设置xmlReader中
    
     
    
          xmlReader.parse(new InputSource(new StringReader(xmldata)))            
    
          //开始解析
    
        } catch(Exception e){
    
          e.printStackTrace();
    
        }
    
      }
    
      .......
    
    }
    
     
    
     
    
     
    
     
    
    public class ContentHandler extends DefaultHandler {
    
     
    
      private String nodeName;
    
      private StringBuilder id;
    
      private StringBuilder name;
    
      private StringBuilder sex;
    
    
    
      @Override
      public void startDocument() throws SAXException {  
    
      //在XML开始解析是调用
        
    
        id = new StringBuilder;
    
        name = new StringBuilder;
    
        sex = new StringBuilder;
      }
    
      @Override
      public void startElement(String uri, String localName,String qName, Attributes attributes) throws SAXException {  
         /*在解析某个节点时调用
    
           * 相当于一个循环,从根节点开始,每读到一个新的节点,
    
            * 便执行一次这个方法,然后把该节点里的所有属性都存到Attributes里,  
    
            *  
    
            * @param uri               xml文档的uri地址,这里直接传入的是inputStream,所以uri为空  
    
            * @param localName         本地名,一般和qName相同      
    
            * @param qName             节点名    
    
            * @param attributes        当前节点下的所有属性都存放到该参数里了    
    
            * @throws SAXException     包含任何sax解析的异常  
    
            */
    
        nodeName = localName; 
    
      }
    
      @Override
      public void characters(char[] ch, int start, int length) throws SAXException {
          /*在解析节点中具体内容时调用
    
            * 该方法里存放的是每个节点里的文本内容,文本内容存到ch数组里, 
    
           * 在此根据判断当前节点名,将内容添加到哪个StringBuilder中
    
           *
     
            * @param ch                用来存放每个节点里的文本内容 
    
            * @param start             文本内容是从哪开始的,如果文本内容前面有1个空格,则start为1,如果没有空格,则start为0
    
            * @param length            ch数组的长度,包含空格
    
            * @throws SAXException     各种sax解析异常
    
            */
    
        if("id".equals(nodeName)){
    
          id.append(ch,start,length);
    
        }else if("name".equals(nodeName)){
    
          name.append(ch,start,length);
    
        }else if("sex".equals(nodeName)){
    
          sex.append(ch,start,length);
    
        }
    
      }
    
    
      @Override
      public void endElement(String uri, String localName, String qName) throws SAXException {
         /*每个节点读取完毕时调用 
    
            *  
    
            * @param uri              xml文档的uri地址,也可以为url,这里直接传入的是inputStream,所以uri为空 
    
            * @param localName        本地名,一般和qName相同
    
            * @param qName            节点名
    
            * @throws SAXException    各种sax解析异常
    
            */
    
        if("student".equals(localName)){
    
          Log.d( "SAX" , "id =" + id.toString().trim());
    
          Log.d( "SAX" , "name=" + name.toString().trim());
    
          Log.d( "SAX" , "sex=" + sex.toString().trim());
    
          //trim()方法,除去字符串两端不可见字符
    
     
    
          id.setLength(0);
    
          name.setLength(0);
    
          sex.setLength(0);
    
          //清空StringBuilder,以免影响下次内容读取
    
        }
    
     
    
      }
    
      @Override
      public void endDocument() throws SAXException {
      //在完成整个XML解析时调用
        super.endDocument(); 
      }
    
    }

    PULL解析方法:

     public class Main{
    
      .......
    
      parseXMLWithPull(xmldata);
    
      //调用PULL解析方法
    
      .......
    
      private void parseXMLWithPull(String xmldata){
    
        try{
    
          XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
    
                  XmlPullParser parser = factory.newPullParser();  
    
          //获得PULL解析器对象
    
          parser.setInput(new StringReader(xmldata));     
    
          // 将XML数据放入解析器
    
          
    
          int eventType = parser.getEventType();
    
          //获得当前节点
    
          
    
          String id = "";
    
          String name = "";
    
          String sex = "";
    
     
    
          while(eventType != paser.END_DOCUMENT){
    
            String nodeName = parser.getName();
    
            switch(eventType){
    
     
    
              //开始解析某个节点
    
              case parser.START_TAG:{
    
                if("id".equals(nodeName)){
    
                  id = parser.nextText();
    
                  //用nextText()方法获得节点内具体内容
    
                }else if("name"equals(nodeName)){
    
                  name = parser.nextText();
    
                }else if("sex".equals(nodeName)){
    
                  sex = parser.nextText();
    
                }
    
                break;
    
              }
    
     
    
              //完成解析某个节点
    
              case parser.END_TAG:{
    
                if("student".equals(nodeName)){          
    
                  Log.d( "PULL" , "id =" + id);
    
                  Log.d( "PULL" , "name=" + name);
    
                  Log.d( "PULL" , "sex=" + sex);
    
                }
    
                break;
    
              }
    
     
    
              default:
    
                break;
    
            }
    
            eventType = parser.next();
    
            //用next()方法获取下一个解析事件
    
        }catch(Exception e){
    
          e.printStackTrace();
    
        }  
    
       }
    
    }

     总结:

      共同点:PULL解析和SAX解析都是事件驱动(事件驱动是基于回调机制对程序运行方法),DOM是文档驱动

      SAX解析(优点):不需要提前把文档读入内存(即占用内存小,相对于DOM解析);解析速度快;

                  (缺点):一旦开始解析,就停不下来,直到解析完整个XML文档。

      PULL解析(优点):类似于SAX,并且PULL解析能控制当什么时候跳出解析(即用break跳出while)        

               

  • 相关阅读:
    在Idea中使用Eclipse编译器
    Idea切换svn分支,类似Eclipse的Switch功能
    Spring AOP详解
    CGLib动态代理原理及实现
    IDEA下搜狗输入法输入中文时卡着不动的参考解决方法
    Nginx反向代理丢失cookie的问题
    redis连接池自动释放
    Redis常用命令
    waitpid之status意义解析
    bash中管道命令返回值如何确定(下)
  • 原文地址:https://www.cnblogs.com/qianbin/p/8414757.html
Copyright © 2011-2022 走看看