SAX解析

与DOM解析的区别:

在使用 DOM 解析XML 文档时,需要读取整个 XML 文档,在内存中构架代表整个 DOM 树的Doucment对象,从而再对XML文档进行操作。此种情况下,如果 XML 文档特别大,就会消耗计算机的大量内存,并且容易导致内存溢出。SAX解析允许在读取文档的时候,即对文档进行处理,而不必等到整个文档装载完才会文档进行操作。

 

SAX采用事件处理的方式解析XML文件

解析器:解析器可以使用JAXP的API创建,创建出SAX解析器后,就可以指定解析器去解析某个XML文档。解析器采用SAX方式在解析某个XML文档时,它只要解析到XML文档的一个组成部分,都会去调用事件处理器的一个方法,解析器在调用事件处理器的方法时,会把当前解析到的xml文件内容作为方法的参数传递给事件处理器

事件处理器:事件处理器由程序员编写,程序员通过事件处理器中方法的参数,就可以很轻松地得到sax解析器解析到的数据,从而可以决定如何对数据进行处理。

                   事件处理器分为四种:ContentHandler(内容处理器)最为多用

ErrorHandler(错误处理器)

DTDHandler(约束处理器)

EntityHandler(实体处理器)

 

SAX解析过程

                   //1. 使用SAXParserFactorynewInstance方法创建产生解析器的工厂

       SAXParserFactory factory = SAXParserFactory.newInstance();

       //2.用工厂的newSAXParser方法创建解析器

       SAXParser parser = factory.newSAXParser();

       //3.得到xml文档读取器

       XMLReader reader = parser.getXMLReader();

       //为读取器设置内容处理器(还可以设置其他处理器,用到什么设置什么)

       reader.setContentHandler(new 你写的处理器());

       //4.利用读取器解析xml文档

       reader.parse("src/book.xml");

         接下来需要写一个类实现ContentHandler这个接口,然后在需要的方法中加入操作

小提示:其实此处实现ContentHandler这个接口会覆盖好多方法,为了不必要的书写,建议继承ContentHandler的实现类DefaultHandler,然后覆盖你所要的方法就OK了。

注:eclipse中覆盖方法的快捷键为Alt+Shift+S,选择Override/Implement Methods

例如:

<?xml version="1.0"encoding="UTF-8"?>

<书架>

    <>

       <书名>javaweb开发</书名>

       <作者>张孝祥</作者>

       <售价>59元</售价>

    </>

    <>

       <书名>JavaScript网页开发</书名>

       <作者>张孝祥</作者>

       <售价>28.00元</售价>

    </>

</书架>

 

//获取整个xml文档内容的处理器

class ListHandler extends DefaultHandler{

    //解析到开始标签的方法

    public voidstartElement(String uri, String localName, String name,

           Attributesatts) throws SAXException {

       System.out.println("<" + name + ">");

    }

//解析到结束标签的方法

    public void endElement(Stringuri, String localName, String name)

       throws SAXException {

       System.out.println("</" + name + ">");

    }

    //解析到内容的方法

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

           throws SAXException {

       System.out.println(newString(ch,start,length));

    }

}

 

//获取到第二个书名标签的值

class BookNameHandler extends DefaultHandler{

//定义currentTag意思为当前的标签

  private String currentTag;

  private int count;  //记住当前解析到了几个书名标签

  @Override

  public voidstartElement(String uri, String localName, String name,

         Attributesattributes) throws SAXException {

     currentTag =name;

     if("书名".equals(currentTag)){

         count++;

     }

  }

 

  @Override

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

         throws SAXException {

     if("书名".equals(currentTag)&& count==1){

         System.out.println(newString(ch,start,length)); //JavaScript网页开发

     }

  }

}

 

//把书的数据封装到javabean的处理器此处为开发中比较常见的方法

class BeanListHandler extends DefaultHandler{

    //建立一个集合,用于存储书对象,在这之前建立一个class放入私有的书名作者之类的变量,提供setget方法

//定义currentTag意思为当前的标签

private String currentTag;

private Book book;

    private List list = new ArrayList();

    public List getBooks(){

       return list;

}

    @Override

    public void startElement(String uri, String localName, String name,

           Attributes attributes) throws SAXException {

       currentTag = name;

           if("".equals(name)){

           book = new Book();

       }

    }

   

    @Override

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

           throws SAXException {

//此处最好写字符串.equals方法,为了将currentTag置为空后,再调用发生空指针异常,或者加上不为空的判断

       if(currentTag != null && currentTag.equals("书名")){

           book.setBookname(new String(ch,start,length));

       }

       if(currentTag != null && currentTag.equals("作者")){

           book.setBookname(new String(ch,start,length));

       }

       if(currentTag != null && currentTag.equals("售价")){

           book.setBookname(new String(ch,start,length));

       }

    }

 

    @Override

    public void endElement(String uri, String localName, String name)

           throws SAXException {

       if(name.equals("")){

           list.add(book);

       }

       //此处将currentTag置为空是防止xml空白处在此用set方法将之前的值覆盖。

currentTag = null;

    }

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值