• Java:XML篇,使用SAX读取并解析XML数据


    1. 描述

    参考:http://www.cnblogs.com/duanxz/archive/2012/08/08/2628416.html,Java中用SAX解析XML,具体包括读写,这篇是读取示范。

    SAX(Simple API for XML) SAX 允许您在读取文档时处理它,它遍历文档并产生事件表示这一过程。 SAX API中主要有四种处理事件的接口,它们分别是ContentHandler,DTDHandler, EntityResolver,ErrorHandler。 实际上只要继承DefaultHandler类 ,再覆盖一部分 处理事件的方法

    1. SAX 它的解析是连续的; 
    2. SAX 数据无法回朔。

    2. 示范代码

    package com.clzhang.sample.xml;
    
    import javax.xml.parsers.SAXParser;
    import javax.xml.parsers.SAXParserFactory;
    
    import org.xml.sax.Attributes;
    import org.xml.sax.SAXException;
    import org.xml.sax.Locator;
    import org.xml.sax.InputSource;
    import org.xml.sax.helpers.DefaultHandler;
    
    /**
     * 参考:http://www.cnblogs.com/duanxz/archive/2012/08/08/2628416.html
     * SAX(Simple API for XML) SAX 允许您在读取文档时处理它,它遍历文档并产生事件表示这一过程。 SAX
     * API中主要有四种处理事件的接口,它们分别是ContentHandler,DTDHandler, EntityResolver,
     * ErrorHandler。 实际上只要继承DefaultHandler类 ,再覆盖一部分 处理事件的方法
     * 1.SAX 它的解析是连续的; 
     * 2.SAX 数据无法回朔。
     * @author Administrator
     */
    class MyContentHandler extends DefaultHandler {
        StringBuffer jsonStringBuffer;
        int frontBlankCount = 0;
    
        public MyContentHandler() {
            jsonStringBuffer = new StringBuffer();
        }
    
        /*
         * 接收用来查找 SAX 文档事件起源的对象。
         * @param locator 可以返回任何 SAX文档事件位置的对象
         */
        @Override
        public void setDocumentLocator(Locator locator) {
            System.out.println(this.toBlankString(this.frontBlankCount)
                    + ">>> set document_locator : (lineNumber = "
                    + locator.getLineNumber() + ",columnNumber = "
                    + locator.getColumnNumber() + ",systemId = "
                    + locator.getSystemId() + ",publicId = "
                    + locator.getPublicId() + ")");
        }
    
        /*
         * 接收文档的开始的通知。
         */
        @Override
        public void startDocument() throws SAXException {
            System.out.println(this.toBlankString(this.frontBlankCount++)
                    + ">>> start document ");
        }
    
        /*
         * 接收文档的结尾的通知。
         */
        @Override
        public void endDocument() throws SAXException {
            System.out.println(this.toBlankString(--this.frontBlankCount)
                    + ">>> end document");
        }
    
        /*
         * 接收元素开始的通知。 
         * @param uri 元素的命名空间 
         * @param localName 元素的本地名称(不带前缀) 
         * @param qName 元素的限定名(带前缀) 
         * @param atts 元素的属性集合
         */
        @Override
        public void startElement(String uri, String localName, String qName,
                Attributes atts) throws SAXException {
            System.out.println(this.toBlankString(this.frontBlankCount++)
                    + ">>> start element : " + qName + "(" + uri + ")");
        }
    
        /*
         * 接收文档的结尾的通知。 
         * @param uri 元素的命名空间 
         * @param localName 元素的本地名称(不带前缀) 
         * @param qName 元素的限定名(带前缀)
         */
        @Override
        public void endElement(String uri, String localName, String qName)
                throws SAXException {
            System.out.println(this.toBlankString(--this.frontBlankCount)
                    + ">>> end element : " + qName + "(" + uri + ")");
        }
    
        /*
         * 开始前缀 URI 名称空间范围映射。 此事件的信息对于常规的命名空间处理并非必需: 当
         * http://xml.org/sax/features/namespaces 功能为 true(默认)时, SAX XML读取器
         * 将自动替换元素和属性名称的前缀。 
         * @param prefix 前缀
         * @param uri 命名空间
         */
        @Override
        public void startPrefixMapping(String prefix, String uri)
                throws SAXException {
            System.out.println(this.toBlankString(this.frontBlankCount++)
                    + ">>> start prefix_mapping : xmlns:" + prefix + " = " + "\""
                    + uri + "\"");
    
        }
    
        /*
         * 结束前缀 URI 范围的映射。
         */
        @Override
        public void endPrefixMapping(String prefix) throws SAXException {
            System.out.println(this.toBlankString(--this.frontBlankCount)
                    + ">>> end prefix_mapping : " + prefix);
        }
    
        /*
         * 接收元素内容中可忽略的空白的通知。 参数意义如下: 
         * @param ch 来自 XML 文档的字符 
         * @param begin 数组中的开始位置 
         * @param length 从数组中读取的字符的个数
         */
        @Override
        public void ignorableWhitespace(char[] ch, int begin, int length)
                throws SAXException {
            StringBuffer buffer = new StringBuffer();
            for (int i = begin; i < begin + length; i++) {
                switch (ch[i]) {
                case '\\':
                    buffer.append("\\\\");
                    break;
                case '\r':
                    buffer.append("\\r");
                    break;
                case '\n':
                    buffer.append("\\n");
                    break;
                case '\t':
                    buffer.append("\\t");
                    break;
                case '\"':
                    buffer.append("\\\"");
                    break;
                default:
                    buffer.append(ch[i]);
                }
            }
            System.out.println(this.toBlankString(this.frontBlankCount)
                    + ">>> ignorable whitespace(" + length + "): "
                    + buffer.toString());
        }
    
        /*
         * 接收处理指令的通知。 参数意义如下: 
         * @param target 处理指令目标 
         * @param data 处理指令数据,如果未提供,则为 null。
         */
        @Override
        public void processingInstruction(String target, String data)
                throws SAXException {
            System.out.println(this.toBlankString(this.frontBlankCount)
                    + ">>> process instruction : (target = \"" + target
                    + "\",data = \"" + data + "\")");
        }
    
        /*
         * 接收跳过的实体的通知。
         * @param name 所跳过的实体的名称。如果它是参数实体,则名称将以 '%' 开头;
         * 如果它是外部 DTD 子集,则将是字符串"[dtd]"
         */
        @Override
        public void skippedEntity(String name) throws SAXException {
            System.out.println(this.toBlankString(this.frontBlankCount)
                    + ">>> skipped_entity : " + name);
        }
    
        /*
         * 接收字符数据的通知。 在DOM中 ch[begin:end] 相当于Text节点的节点值(nodeValue)
         */
        @Override
        public void characters(char[] ch, int begin, int length)
                throws SAXException {
            StringBuffer buffer = new StringBuffer();
            for (int i = begin; i < begin + length; i++) {
                switch (ch[i]) {
                case '\\':
                    buffer.append("\\\\");
                    break;
                case '\r':
                    buffer.append("\\r");
                    break;
                case '\n':
                    buffer.append("\\n");
                    break;
                case '\t':
                    buffer.append("\\t");
                    break;
                case '\"':
                    buffer.append("\\\"");
                    break;
                default:
                    buffer.append(ch[i]);
                }
            }
            System.out.println(this.toBlankString(this.frontBlankCount)
                    + ">>> characters(" + length + "): " + buffer.toString());
        }
    
        // 缩进控制
        private String toBlankString(int count) {
            StringBuffer buffer = new StringBuffer();
            for (int i = 0; i < count; i++)
                buffer.append("    ");
            return buffer.toString();
        }
    }
    
    public class SAXReadTest {
        public static void main(String args[]) throws Exception {
            long lasting = System.currentTimeMillis();
            SAXParserFactory sf = SAXParserFactory.newInstance();
            SAXParser sp = sf.newSAXParser();
    
            MyContentHandler ins = new MyContentHandler();
            sp.parse(new InputSource("bbs.xml"), ins);
            System.out.println("运行时间:" + (System.currentTimeMillis() - lasting)
                    + " 毫秒");
        }
    }
  • 相关阅读:
    python命令行工具模块-click
    python项目代码打包成Docker镜像
    背包九讲
    秒杀项目的3个奇数问题:并发队列的选择,请求接口的合理设计,高并发下的数据安全
    java类加载过程
    索引失效
    java面试
    进程间通信
    HashMap在Jdk1.7和1.8中的实现
    十大排序算法
  • 原文地址:https://www.cnblogs.com/nayitian/p/2867240.html
Copyright © 2020-2023  润新知