XML(十)- SAX解析

XML解析之 SAX解析

SAX介绍

  SAX的全称是Simple APIs for XML,也即XML简单应用程序接口。

  与DOM不同,SAX提供的访问模式是一种顺序模式,这是一种快速读写XML数据的方式。

  当使用SAX分析器对XML文档进行分析时,会触发一系列事件,并激活相应的事件处理函数,应用程序通过这些事件处理函数实现对XML文档的访问,因而SAX接口也被称作事件驱动接口

  局限性:

  1. SAX分析器在对XML文档进行分析时,触发了一系列的事件,由于事件触发本身是有时序性的,因此,SAX提供的是一种顺序访问机制,对于已经分析过的部分,不能再倒回去重新处理。即,一旦经过了某个元素,我们没有办法返回去再去访问它。

  2. SAX分析器只做了一些简单的工作,大部分工作还要由应用程序自己去做。也就是说,SAX分析器在实现时,只是顺序地检查XML文档中的字节流,判断当前字节是XML语法中的哪一部分、是否符合XML语法,然后再触发相应的事件,而事件处理函数本身则要由应用程序自己来实现。同DOM分析器相比,SAX分析器缺乏灵活性。

  优势:

  然而,由于SAX分析器实现简单,对内存要求比较低,(SAX不必将整个XML文档加载到内存当中,因此它占据内存要比DOM小), 因此实现效率比较高。对于大型的XML文档来说,通常会用SAX而不是DOM。并且对于那些只需要访问XML文档中的数据而不对文档进行更改的应用程序来说,SAX分析器更为合适。

SAX分析器

  XML解析器实际上就是一段代码,它读入一个XML文档并分析其结构。

  分类:

    带校验的解析器

    不校验的解析器(效率高)

    支持DOM的解析器(W3C的官方标准)

    支持SAX的解析器(事实上的工业标准)

  SAX是事件驱动的,文档的读入过程就是SAX的解析过程。

  在读入的过程中,遇到不同的项目,解析器会调用不同的处理方法。

SAX解析实例

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

<bookstore>
    <book category="children">
          <title lang="en">Harry Potter</title>
          <author>J K. Rowling</author>
          <year>2005</year>
          <price>29.99</price>
    </book>

    <book category="cooking">
          <title lang="en">Everyday Italian</title>
          <author>Giada De Laurentiis</author>
          <year>2005</year>
          <price>30.00</price>
    </book>

    <book category="web">
          <title lang="en">Learning XML</title>
          <author>Erik T. Ray</author>
          <year>2003</year>
          <price>39.95</price>
    </book>

    <book category="web">
          <title lang="en">XQuery Kick Start</title>
          <author>James McGovern</author>
          <author>Per Bothner</author>
          <author>Kurt Cagle</author>
          <author>James Linn</author>
         <author>Vaidyanathan Nagarajan</author>
          <year>2003</year>
          <price>49.99</price>
    </book>

</bookstore>

用SAX解析这个文档的Java代码:

package cn.org.kingdom.sax;
import java.io.File;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
/**
 * SAX解析XML 查看事件调用
 */
public class SaxTest1 {
    public static void main(String[] args) throws Exception {
        // step 1: 获得SAX解析器工厂实例
        SAXParserFactory factory = SAXParserFactory.newInstance();
        // step 2: 获得SAX解析器实例
        SAXParser parser = factory.newSAXParser();
        // step 3: 开始进行解析
        // 传入待解析的文档的处理器
        parser.parse(new File("src/persons.xml"), new MyHandler());
    }
}

class MyHandler extends DefaultHandler {
    @Override
    public void startDocument() throws SAXException {
        System.out.println("start document -> parse begin");
    }

    @Override
    public void endDocument() throws SAXException {

        System.out.println("end document -> parse finished");
    }

    @Override
    public void startElement(String uri, String localName, String qName,
            Attributes attributes) throws SAXException {
        System.out.println("start element-----------");
        System.out.println("    localName: " + localName);
        System.out.println("    qName: " + qName);

    }

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

    @Override
    public void endElement(String uri, String localName, String qName)
            throws SAXException {
        System.out.println("end element-----------");
        System.out.println("    localName: " + localName);
        System.out.println("    qName: " + qName);
    }
}

解析代码2

package cn.org.kingdom.sax;

import java.io.File;
import java.util.Stack;

import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

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

/**
 * SAX解析XML
 *
 */
public class SaxTest2 {

    public static void main(String[] args) throws Exception {
        // step 1: 获得SAX解析器工厂实例
        SAXParserFactory factory = SAXParserFactory.newInstance();
        // step 2: 获得SAX解析器实例
        SAXParser parser = factory.newSAXParser();
        // step 3: 开始进行解析
        // 传入待解析的文档的处理器
        parser.parse(new File("src/test.xml"), new MySAXHandler());
    }
}

class MySAXHandler extends DefaultHandler {
    // 使用栈这个数据结构来保存
    private Stack<String> stack = new Stack<String>();
    // 数据
    private String title;
    private String author;
    private String year;
    private double price;

    @Override
    public void startDocument() throws SAXException {
        System.out.println("start document -> parse begin");
    }

    @Override
    public void endDocument() throws SAXException {

        System.out.println("end document -> parse finished");
    }

    @Override
    public void startElement(String uri, String localName, String qName,
            Attributes attributes) throws SAXException {
        // System.out.println("start element-----------");
        // System.out.println("    localName: " + localName);
        // System.out.println("    qName: " + qName);

        // 将标签名压入栈
        stack.push(qName);

        // 处理属性
        for (int i = 0; i < attributes.getLength(); ++i) {
            String attrName = attributes.getQName(i);
            String attrValue = attributes.getValue(i);
            System.out.println("属性: " + attrName + "=" + attrValue);

        }

    }

    @Override
    public void characters(char[] ch, int start, int length)
            throws SAXException {
        // System.out.println("characters-----------");
        // System.out.println("    ch: " + Arrays.toString(ch) );
        // System.out.println("    ch: " + ch);
        // System.out.println("    start: " + start);
        // System.out.println("    length: " + length);

        // 取出标签名
        String tag = stack.peek();

        if ("title".equals(tag)) {
            title = new String(ch, start, length);

        } else if ("author".equals(tag)) {
            author = new String(ch, start, length);
        } else if ("year".equals(tag)) {
            year = new String(ch, start, length);
        } else if ("price".equals(tag)) {
            price = Double.parseDouble(new String(ch, start, length));
        }
    }

    @Override
    public void endElement(String uri, String localName, String qName)
            throws SAXException {
        // System.out.println("end element-----------");
        // System.out.println("    localName: " + localName);
        // System.out.println("    qName: " + qName);
        stack.pop();// 表示该元素解析完毕,需要从栈中弹出标签
        if ("book".equals(qName)) {
            System.out.println("Book info: -------");
            System.out.println("    title: " + title);
            System.out.println("    author: " + author);
            System.out.println("    year: " + year);
            System.out.println("    price: " + price);
            System.out.println();
        }
    }
}

输出结果

start document -> parse begin
属性: category=children
属性: lang=en
Book info: -------
    title: Harry Potter
    author: J K. Rowling
    year: 2005
    price: 29.99

属性: category=cooking
属性: lang=en
Book info: -------
    title: Everyday Italian
    author: Giada De Laurentiis
    year: 2005
    price: 30.0

属性: category=web
属性: lang=en
Book info: -------
    title: Learning XML
    author: Erik T. Ray
    year: 2003
    price: 39.95

属性: category=web
属性: lang=en
Book info: -------
    title: XQuery Kick Start
    author: Vaidyanathan Nagarajan
    year: 2003
    price: 49.99

end document -> parse finished
时间: 2024-10-29 19:11:09

XML(十)- SAX解析的相关文章

iOS中的数据解析(XML,JSON),SAX解析,DOM解析

第三方 SAT解析 #import "SAXTableViewController.h" #import "Student.h" @interface SAXTableViewController ()<NSXMLParserDelegate> @property (nonatomic, retain) NSMutableArray *dataSourse; // 存储学生对象 @property (nonatomic, retain) Student

Android解析XML之SAX解析器

SAX(Simple API for XML)解析器是一种基于事件的解析器,它的核心是事件处理模式,主要是围绕着事件源以及事件处理器来工作的.当事件源产生事件后,调用事件处理器相应的处理方法,一个事件就可以得到处理.在事件源调用事件处理器中特定方法的时候,还要传递给事件处理器相应事件的状态信息,这样事件处理器才能够根据提供的事件信息来决定自己的行为. SAX解析器的优点是解析速度快,占用内存少.非常适合在Android移动设备中使用. SAX相关类及API DefaultHandler:是一个事

XML之SAX解析模型

DOM解析会把整个XML文件全部映射成Document里的树形结构,当遇到比较大的文件时,它的内存占用很大,查找很慢 SAX就是针对这种情况出现的解决方案,SAX解析器会从XML文件的起始位置起进行解析,同时根据已经定义好的事件处理器,来决定当前所解析的部分是否有必要进行记录并存储 import java.io.File; import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; public c

XML的sax解析

1)两种解析方式 dom解析:一次性把整个xml文件读入内容,构建document树. 问题:比较消耗内存     不适合读取大文件 sax解析: 为了解决读取大文件的问题,引入sax解析 原理:读取一点(xml的某个部分),解析一点 sax,simple api for xml 2) sax的api 官方jaxp的sax .  org.xm.sax.* 2.1 读取xml文件 a)创建SAXParserFactory对象 b)获取一个SAXParser对象 c)获取一个XMLReader对象

XML(三)Sax解析XML

  两种解析方式: dom4j 和 sax 解析思想: book2.xml <?xml version="1.0" encoding="UTF-8"?> <书架> <书> <书名>JAVA</书名> <作者>XXXXXX</作者> <售价>23333</售价> </书> <书> <书名>ANDROID</书名>

XML数据结构 SAX 解析

?SAX解析 SAX:Simple API for XML.基于事件驱动的解析?方式,逐?行解析 数据.(采?用协议回调机制) ?NSXMLParser类 NSXMLParser是iOS?自带的XML解析类.采?用SAX?方式解析数据. 解析过程由NSXMLParserDelegate协议?方法回调 解析过程:开始标签->取值->结束标签->取值 <?xml version = "1.0" encoding = "UTF-8"?> &l

【文件处理】xml 文件 SAX解析

SAX的全称是Simple APIs for XML,也即XML简单应用程序接口. 与DOM不同,SAX提供的访问模式是一种顺序模式,这是一种快速读写XML数据的方式. 当使用SAX分析器对XML文档进行分析时,会触发一系列事件,并激活相应的事件处理函数,应用程序通过这些事件处理函数实现对XML文档的访问,因而SAX接口也被称作事件驱动接口. 局限性: 1. SAX分析器在对XML文档进行分析时,触发了一系列的事件,由于事件触发本身是有时序性的,因此,SAX提供的是一种顺序访问机制,对于已经分析

使用jaxp对比xml进行SAX解析

package cn.itcast.sax; import java.io.IOException; import javax.xml.parsers.ParserConfigurationException; import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; import org.xml.sax.Attributes; import org.xml.sax.ContentHandler;

XML.03-DOM和SAX解析

body,td { font-family: calibri; font-size: 10pt } XML.03-DOM和SAX解析 XML的DOM解析 解析 处理 回写 XML的SAX解析 SAX和DOM方式的不同: SAX解析原理 SAX解析范例 解析xml常用的有两种方式,DMO和SAX DOM和SAX的区别: DOM: 在内存中生成树桩结构 优点是可以支持增删改查各种操作 缺点在于,如果文档过大的时候,可能会产生内存溢出的风险 SAX: 基于事件驱动,边读边解析 优点:占用内存小 缺点,