XML的解析方式2——SAX方式解析XML


)
参考 四种生成和解析XML文档的方法详解(介绍+优缺点比较+示例)

XML解析方式

1. DOM解析

见上一篇博客:XML的解析方式1——DOM方式解析XML

2.SAX方式解析

【优势】

  1. 不需要等待所有数据都被处理,分析就能立即开始。
  2. 只在读取数据时检查数据,不需要保存在内存中。
  3. 可以在某个条件得到满足时停止解析,不必解析整个文档。
  4. 效率和性能较高,能解析大于系统内存的文档。

【缺点】

  1. 需要应用程序自己负责TAG的处理逻辑(例如维护父/子关系等),文档越复杂程序就越复杂
  2. 单向导航,无法定位文档层次,很难同时访问同一文档的不同部分数据,不支持XPath

代码示例

XmlDocument接口

package com.vincient.test;

/**
 * @Author: Vincient
 * @Description:
 * @Date: 2018/十月/30
 **/
public interface XmlDocument {
    public void parseXml(String fileName);
}

SAXDemo类

package com.vincient.test;

import org.xml.sax.SAXException;

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

/**
 * @Author: Vincient
 * @Description:
 * @Date: 2018/十月/31
 **/
public class SAXDemo implements XmlDocument {
    @Override
    public void parseXml(String fileName) {
        SAXParserFactory saxfac = SAXParserFactory.newInstance();
        try {
            SAXParser saxParser = saxfac.newSAXParser();
            InputStream inputStream = new FileInputStream(fileName);
            saxParser.parse(inputStream, new MySAXHandler());
        } catch (ParserConfigurationException e) {
            e.printStackTrace();
        } catch (SAXException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        SAXDemo saxDemo = new SAXDemo();
        saxDemo.parseXml("此处为文件uri");
    }
}

MySAXHandler类

package com.vincient.test;

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

/**
 * @Author: Vincient
 * @Description:
 * @Date: 2018/十月/31
 **/
public class MySAXHandler extends DefaultHandler {
    boolean hasAttribute = false;
    Attributes attributes = null;

    @Override
    public void startDocument() throws SAXException {
        System.out.println("文档打印开始了");
    }

    @Override
    public void endDocument() throws SAXException {
        System.out.println("文档打印结束了");
    }

    @Override
    public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
        if (qName.equals("users")) {
            return;
        }
        if (qName.equals("user")) {
            return;
        }
        if (attributes.getLength() > 0) {
            this.attributes = attributes;
            this.hasAttribute = true;
        }
    }

    @Override
    public void endElement(String uri, String localName, String qName) throws SAXException {
        if (hasAttribute && (attributes != null)) {
            for (int i = 0; i < attributes.getLength(); i++) {
                System.out.println(attributes.getQName(0) + ":" + attributes.getValue(0));
            }
        }
    }

    @Override
    public void characters(char[] ch, int start, int length) throws SAXException {
        System.out.println(new String(ch, start, length));
    }
}

user.xml

<?xml version="1.0" encoding="UTF-8"?>
<users>
    <user id="0">
        <name>Alexia</name>
        <age>23</age>
        <sex>Female</sex>
    </user>
    <user id="1">
        <name>Edward</name>
        <age>24</age>
        <sex>Male</sex>
    </user>
    <user id="2">
        <name>wjm</name>
        <age>23</age>
        <sex>Female</sex>
    </user>
    <user id="3">
        <name>wh</name>
        <age>24</age>
        <sex>Male</sex>
    </user>
</users>

执行结果

文档打印开始了

    

        
Alexia

        
23

        
Female

    

    

        
Edward

        
24

        
Male

    

    

        
wjm

        
23

        
Female

    

    

        
wh

        
24

        
Male

    


文档打印结束了

代码中的注意点

  1. 本样例代码本质上是通过基础DefaultHandler类来实现XML的SAX方式解析。而DefaultHandler的方法执行简化顺序如下:
Created with Raphaël 2.2.0 开始 startDocument() startElement() characters() XML扫描完毕? 结束 yes no
  1. characters方法中,ch把所解析的xml的所有数据都保存进来,且ch初始化为2K数据。 start是一个节点">“的位置。length就是”>“到下一个”<"的长度。

猜你喜欢

转载自blog.csdn.net/weixin_42908976/article/details/83652913