zoukankan      html  css  js  c++  java
  • XML SAX解析 附Java程序实例

     

    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文档为例:

    <?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 com.example.xml.sax;
    
    import java.io.File;
    import java.util.Arrays;
    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 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("books.xml"), new MyHandler());
    
        }
    }
    
    class MyHandler extends DefaultHandler
    {
        // 使用栈这个数据结构来保存
        private Stack<String> stack = new Stack<String>();
    
        @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: " + Arrays.toString(ch) );
            System.out.println("    ch: " + ch);
            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);
    
        }
    }

      解析程序第二版:

    package com.example.xml.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("books.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();
            }
    
        }
    }
    SaxTest2

      SaxTest2程序输出:

    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
    Console output

    参考资料

      圣思园张龙老师XML教学视频。

      Java API文档:http://docs.oracle.com/javase/7/docs/api/index.html

     

  • 相关阅读:
    use evolation+mapi with exhange mode
    python open file mode description
    5 reasons why you should learn python programming
    文本从尾到头输出
    安装部署lamp,来测试rediect
    python for ,loop ,else condition test
    python logging usage
    去除重复行
    [WTL]WTL for MFC Programming实践篇 一个自定义ComboBox的移植过程
    subsonic已死,db4o将死
  • 原文地址:https://www.cnblogs.com/mengdd/p/3114177.html
Copyright © 2011-2022 走看看