SAX解析XML文档

1、简介

前面我们介绍过利用DOM解析XML文档,Dom解析功能强大,可增删改查,操作时会将XML文档读到内存,因此适用于小文档;SAX解析是从头到尾逐行逐个元素解析,修改较为不便,但适用于只读的大文档。

SAX采用事件驱动的方式解析XML。套用别人的解释,如同在电影院看电影一样,从头到尾看一遍,不能回退(Dom可来来回回读取),在看电影的过程中,每遇到一个情节,都会调用大脑去接收处理这些信息。SAX也是相同的原理,每遇到一个元素节点,都会调用相应的方法来处理。在SAX的解析过程中,读取到文档开头、文档结尾,元素的开头和元素结尾都会调用相应方法,我们可以在这些方法中进行相应事件处理。

2、解析步骤

(1)通过SAXParserFactory的静态方法newInstance()方法获取SAXParserFactory实例对象factory

SAXParserFactory factory = SAXParserFactory.newInstance();

(2)通过SAXParserFactory实例的newSAXParser()方法返回SAXParser实例parser

SAXParser parser = factory.newSAXParser();

(3)创建一个类继承DefaultHandler,重写其中的一些方法进行业务处理

import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
public class SAXParserHandler extends DefaultHandler{

    // 用来标示解析开始
    @Override
    public void startDocument() throws SAXException {

    }

    // 用来标示解析结束
    @Override
    public void endDocument() throws SAXException {

    }

    // 用来遍历XML文件的开始标签
    @Override
    public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
        super.startElement(uri, localName, qName, attributes);
    }

    // 用来遍历XML文件的结束标签
    @Override
    public void endElement(String uri, String localName, String qName) throws SAXException {
        super.endElement(uri, localName, qName);
    }

    // 处理在XML文件中读到的内容,第一个参数为文件的字符串内容,后面两个参数是读到的字符串在这个数组中的起始位置和长度,使用new String(ch,start,length)就可以获取内容
    @Override
    public void characters(char[] ch, int start, int length) throws SAXException {
        super.characters(ch, start, length);
    }
}

(4)创建Handler类对象实例

// 定义SAXParserHandler对象
SAXParserHandler handler = new SAXParserHandler();

(5)解析XML文档

saxParser.parse(path, handler);

3、解析实例

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

import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import java.io.IOException;

/**
 * Created by xxx on 2017/3/30.
 */
public class SaxParserXmlCode extends DefaultHandler {
    private int bookIndex = 0;
    private String currentTag = null;

    // 用来标示解析开始
    @Override
    public void startDocument() throws SAXException {
        System.out.println("SAX解析开始...");
    }

    // 用来标示解析结束
    @Override
    public void endDocument() throws SAXException {
        System.out.println("SAX解析结束...");
    }

    // 用来遍历XML文件的开始标签
    @Override
    public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
        // 调用DefaultHandler类的startElement方法
        super.startElement(uri, localName, qName, attributes);
        currentTag = qName;
        // 开始解析book元素节点
        if(qName.equals("book")){
            ++ bookIndex;
            System.out.println("开始解析第" + bookIndex + "个节点...");
            // 已知book元素节点下的属性名称,根据属性名称获取属性值
            /*String value = attributes.getValue("category");
            System.out.println("value->"+value);*/

            // 不知道book元素节点下的属性名称以及个数
            int size = attributes.getLength();
            for(int i = 0;i < size; ++i){
                System.out.println(attributes.getQName(i) + ":" + attributes.getValue(i));
            }
        }else if(!qName.equals("bookstore")){
            System.out.print(qName + ":");
        }
    }

    // 用来遍历XML文件的结束标签
    @Override
    public void endElement(String uri, String localName, String qName) throws SAXException {
        super.endElement(uri, localName, qName);
        // 判断一个节点是否解析完
        if(qName.equals("book")){
            System.out.println("结束解析第" + bookIndex + "个节点...");
        }
    }

    @Override
    public void characters(char[] ch, int start, int length) throws SAXException {
        super.characters(ch, start, length);
        String text = new String(ch, start, length);
        if(!text.trim().equals("")){
            System.out.println(text);
        }

        if("title".equals(currentTag)) {
            System.out.println("title=======" + text);
        }else if("price".equalsIgnoreCase(currentTag)){
            System.out.println("price=======" + text);
        }
        currentTag = null;
    }


    public static void main(String[] args) {
        String path = "F:\\datafortag\\book.xml";
        try {
            // 通过SAXParserFactory的静态方法newInstance()方法获取SAXParserFactory实例对象factory
            SAXParserFactory factory = SAXParserFactory.newInstance();
            // 通过SAXParserFactory实例的newSAXParser()方法返回SAXParser实例parser
            SAXParser saxParser = factory.newSAXParser();
            // 定义SAXParserHandler对象
            SaxParserXmlCode handler = new SaxParserXmlCode();
            // 解析XML文档
            saxParser.parse(path, handler);
        } catch (ParserConfigurationException e) {
            e.printStackTrace();
        } catch (SAXException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

附book.xml

<?xml version="1.0" encoding="utf-8"?><bookstore>
    <book category="Java">
        <title lang="chi">Java编程思想</title> 
        <author>Bruce Eckel</author> 
        <year>2007</year> 
        <price>108.00</price> 
    </book>

    <book category="C++">
        <title lang="en">Effective C++</title> 
        <author>Scott Meyers</author> 
        <year>2006</year> 
        <price>58.00</price> 
    </book>
</bookstore>
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值