XML(十)- SAX解析

来源:互联网 发布:易语言客户端发送数据 编辑:程序博客网 时间:2024/05/17 04:28
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=enBook info: -------    title: Harry Potter    author: J K. Rowling    year: 2005    price: 29.99属性: category=cooking属性: lang=enBook info: -------    title: Everyday Italian    author: Giada De Laurentiis    year: 2005    price: 30.0属性: category=web属性: lang=enBook info: -------    title: Learning XML    author: Erik T. Ray    year: 2003    price: 39.95属性: category=web属性: lang=enBook info: -------    title: XQuery Kick Start    author: Vaidyanathan Nagarajan    year: 2003    price: 49.99end document -> parse finished

 

原创粉丝点击