SAX解析XML文件

  • Post author:
  • Post category:其他




SAX解析简介

SAX(Simple API for XML)是一种以事件驱动的XML API,是XML解析的方式之一。DOM解析会将XML全部加载到内存中,再进行解析。SAX与DOM不同的是它边扫描边解析,自顶向下依次解析,由于边扫描边解析,所以它解析XML具有速度快,占用内存少的优点。




SAX解析步骤

SAX解析的核心步骤有如下几步:

  1. 得到xml文件对应的资源,可以是xml的输入流,文件和uri
  2. 得到SAX解析工厂(SAXParserFactory)
  3. 由解析工厂生产一个SAX解析器(SAXParser)
  4. 传入输入流和handler给解析器,调用parse()解析



SAX解析案例

1、xml文件

<?xml version="1.0" encoding="utf-8"?>
<contract>
    <member id="001">
        <name>张三</name>
        <age>18</age>
        <tel>110</tel>
    </member>
    <member id="002">
        <name>李四</name>
        <age>18</age>
        <tel>120</tel>
    </member>
</contract>

2、JavaBean

public class Member {
    private Integer id;
    private String name;
    private Integer age;
    private Integer tel;

    public Member() {
    }

    public Member(Integer id, String name, Integer age, Integer tel) {
        this.id = id;
        this.name = name;
        this.age = age;
        this.tel = tel;
    }

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    public Integer getTel() {
        return tel;
    }

    public void setTel(Integer tel) {
        this.tel = tel;
    }

    @Override
    public String toString() {
        return "Member{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", age=" + age +
                ", tel=" + tel +
                '}';
    }
}

3、新建一个类MyParseHandler.java,该类继承DefaultHandler.java,并重写DefaultHandler类中的五个核心方法。

  • startDocument():文档解析开始时调用,该方法只会调用一次

  • startElement(String uri, String localName, String qName, Attributes attributes):标签解析开始时调用

     uri:xml文档的命名空间
     localName:标签的名字
     qName:带命名空间的标签的名字
     attributes:标签的属性集
    
  • characters(char[] ch, int start, int length):解析标签的内容的时候调用

     ch:当前读取到的TextNode(文本节点)的字节数组
     start:字节开始的位置,为0则读取全部
     length:当前TextNode的长度
    
  • endElement(String uri, String localName, String qName):标签解析结束后调用

  • endDocument():文档解析结束后调用,该方法只会调用一次

MyParseHandler类的具体代码如下

public class MyDefaultHandler extends DefaultHandler {

    private List<Member> members = new ArrayList<>();
    private Member member; 
    String value = null;

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

    @Override
    public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
        /*
         * qName是当前解析的节点名称
         * attributes是当前解析的节点的所有属性
         */

        if ("member".equals(qName)) {
            //如果当前解析的是member节点,则创建一个Member对象,并取得属性值(id)
            member = new Member();
            String idValue = attributes.getValue("id");
            member.setId(Integer.parseInt(idValue));
        }
    }

    @Override
    public void characters(char[] ch, int start, int length) throws SAXException {
        value = new String(ch,start,length);
    }

    @Override
    public void endElement(String uri, String localName, String qName) throws SAXException {
        if("name".equals(qName)) {
            member.setName(value);
        }else if ("age".equals(qName)) {
            member.setAge(Integer.parseInt(value));
        }else if ("tel".equals(qName)) {
            member.setTel(Integer.parseInt(value));
        }else if ("member".equals(qName)) {
            members.add(member);
            member = null;
        }
    }

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

    public List<Member> getMembers() {
        return this.members;
    }
}


测试类代码如下

public class TestDemoI {
    public static void main(String[] args) throws Exception{
        //设置要读取的文件对象
        File file = new File("E:" + File.separator + "Telephone.xml");
        // 通过SAXParserFactory的静态方法newInstance()获取SAXParserFactory的实例
        SAXParserFactory factory = SAXParserFactory.newInstance();
        // 通过SAXParserFactory的实例的newSAXParser()方法获取SAXParser实例
        SAXParser parser = factory.newSAXParser();
        // 定义一个自己的Handler类,继承DefaultHandler
        MyDefaultHandler handler = new MyDefaultHandler();
        parser.parse(file, handler);
        List<Member> members = handler.getMembers();
        System.out.println(members);
    }
}

输出结果如下

SAX解析开始
SAX解析结束
[Member{id=1, name='张三', age=18, tel=110}, Member{id=2, name='李四', age=19, tel=120}]



版权声明:本文为qq_36025972原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。