关闭

快速解析XML

标签: java
230人阅读 评论(0) 收藏 举报
分类:

  SAX解析XML文件采用事件驱动的方式进行,也就是说,SAX是逐行扫描文件,遇到符合条件的设定条件后就会触发特定的事件,回调你写好的事件处理程序。使用SAX的优势在于其解析速度较快,相对于DOM而言占用内存较少。而且SAX在解析文件的过程中得到自己需要的信息后可以随时终止解析,并不一定要等文件全部解析完毕。凡事有利必有弊,其劣势在于SAX采用的是流式处理方式,当遇到某个标签的时候,它并不会记录下以前所遇到的标签,也就是说,在处理某个标签的时候,比如在startElement方法中,所能够得到的信息就是标签的名字属性,至于标签内部的嵌套结构,上层标签、下层标签以及其兄弟节点的名称等等与其结构相关的信息都是不得而知的。实际上就是把XML文件的结构信息丢掉了,如果需要得到这些信息的话,只能你自己在程序里进行处理了。所以相对DOM而言,SAX处理XML文档没有DOM方便,SAX处理的过程相对DOM而言也比较复杂。

        SAX采用事件处理的方式解析XML文件,利用 SAX 解析 XML 文档,涉及两个部分:解析器和事件处理器:
解析器可以使用JAXP的API创建,创建出SAX解析器后,就可以指定解析器去解析某个XML文档。
解析器采用SAX方式在解析某个XML文档时,它只要解析到XML文档的一个组成部分,都会去调用事件处理器的一个方法,解析器在调用事件处理器的方法时,会把当前解析到的xml文件内容作为方法的参数传递给事件处理器。
事件处理器由程序员编写,程序员通过事件处理器中方法的参数,就可以很轻松地得到sax解析器解析到的数据,从而可以决定如何对数据进行处理。

备注说明:SAX API中主要有四种处理事件的接口,它们分别是ContentHandlerDTDHandler, EntityResolver 和 ErrorHandler 

 这里使用最多的就是ContentHandler,仔细阅读 API文档,了解常用方法:startElement、endElement、characters等

 1.startElement方法说明

[java]

  1. void startElement(String uri,  
                      String localName,  
                      String qName,  
                      Attributes atts)  
                      throws SAXException  
    方法说明:  
    解析器在 XML 文档中的每个元素的开始调用此方法;对于每个 startElement 事件都将有相应的 endElement 事件(即使该元素为空时)。所有元素的内容都将在相应的 endElement 事件之前顺序地报告。  
      
    参数说明:  
    uri - 名称空间 URI,如果元素没有名称空间 URI,或者未执行名称空间处理,则为空字符串  
    localName - 本地名称(不带前缀),如果未执行名称空间处理,则为空字符串  
    qName - 限定名(带有前缀),如果限定名不可用,则为空字符串 (标签名) 
    atts - 连接到元素上的属性。如果没有属性,则它将是空 Attributes 对象。在 startElement 返回后,此对象的值是未定义的(标签名属性)
    

 2.endElement方法说明

[java]

  1.  

  2. void endElement(String uri,  
                    String localName,  
                    String qName)  
                    throws SAXException接收元素结束的通知。   
    SAX 解析器会在 XML 文档中每个元素的末尾调用此方法;对于每个 endElement 事件都将有相应的 startElement 事件(即使该元素为空时)。  
      
    参数:  
    uri - 名称空间 URI,如果元素没有名称空间 URI,或者未执行名称空间处理,则为空字符串  
    localName - 本地名称(不带前缀),如果未执行名称空间处理,则为空字符串  
    qName - 限定的 XML 名称(带前缀),如果限定名不可用,则为空字符串
    


3.characters方法

[java] 

  1. void characters(char[] ch,  
                    int start,  
                    int length)  
                    throws SAXException  
    接收字符数据的通知,可以通过new String(ch,start,length)构造器,创建解析出来的字符串文本.  
    参数:  
    ch - 来自 XML 文档的字符  
    start - 数组中的开始位置  
    length - 从数组中读取的字符的个数
    


说明:xml中每个标签的文本内容是在characters方法里处理的。

比如在如下:

  1. <?xml version="1.0" encoding="UTF-8"?>  
    <!DOCTYPE 四大名著[  
    <!ELEMENT 四大名著 (西游记,红楼梦)>  
    <!ATTLIST 西游记 id ID #IMPLIED>  
    ]>  
    <四大名著>  
        <西游记 id="x001">  
            <作者>吴承恩</作者>  
        </西游记>  
        <红楼梦 id="x002">  
            <作者>曹雪芹</作者>  
        </红楼梦>  
    </四大名著>
    

在<西游记 id="x001"><作者>吴承恩</作者></西游记>里

吴承恩这个文本就是在characters方法里处理的。

其中<西游记></西游记>和<作者></作者>是标签(qname)

id="x001"是属性(atts)和值

其它方法请参考api数据



下面我们就具体讲解sax解析的操作.

一.我们通过XMLReaderFactory、XMLReader完成,步骤如下

[java]

  1. 1.通过XMLReaderFactory创建XMLReader对象  
    XMLReader reader = XMLReaderFactory.createXMLReader();  
    2. 设置事件处理器对象  
    reader.setContentHandler(new MyDefaultHandler());  
    3.读取要解析的xml文件  
    FileReader fileReader =new FileReader(new File("src\\sax\\startelement\\web.xml"));  
    4.指定解析的xml文件  
    reader.parse(new InputSource(fileReader));
    


案例:通过案例对uri、localName、qName和attribute参数有更加深入的了解

1.首先创建要解析的web.xml文件,内容如下

[html]

  1. <?xml version="1.0" encoding="UTF-8"?>  
    <web-app version="2.5"   
        xmlns:csdn="http://java.sun.com/xml/ns/javaee"   
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"   
        xsi:schemaLocation="http://java.sun.com/xml/ns/javaee   
        http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">  
      <csdn:display-name></csdn:display-name>     
    </web-app>  
    <!--   
    uri - 名称空间 URI,如果元素没有任何名称空间 URI,或者没有正在执行名称空间处理,则为空字符串。  
    xml namespace-xmlns  
    localName - 本地名称(不带前缀),如果没有正在执行名称空间处理,则为空字符串。  
    qName - 限定的名称(带有前缀),如果限定的名称不可用,则为空字符串。  
    attributes - 附加到元素的属性。如果没有属性,则它将是空的 Attributes 对象。   
     -->
    


2.创建解析测试类及事件处理的内部类代码如下

[java]

  1. package sax.startelement;  
      
    import java.io.File;  
    import java.io.FileReader;  
      
    import org.junit.Test;  
    import org.xml.sax.Attributes;  
    import org.xml.sax.InputSource;  
    import org.xml.sax.SAXException;  
    import org.xml.sax.XMLReader;  
    import org.xml.sax.helpers.DefaultHandler;  
    import org.xml.sax.helpers.XMLReaderFactory;  
      
    public class Demo3 {  
      
        @Test  
        public void test() throws Exception {  
            // 通过XMLReaderFactory创建XMLReader对象  
            XMLReader reader = XMLReaderFactory.createXMLReader();  
            // 设置事件处理器对象  
            reader.setContentHandler(new MyDefaultHandler());  
            // 读取要解析的xml文件  
            FileReader fileReader = new FileReader(new File(  
                    "src\\sax\\startelement\\web.xml"));  
            // 指定解析的xml文件  
            reader.parse(new InputSource(fileReader));  
        }  
      
        // 自定义的解析类,通过此类中的startElement了解uri,localName,qName,Attributes的含义  
        class MyDefaultHandler extends DefaultHandler {  
      
            @Override  
            public void startElement(String uri, String localName, String qName,  
                    Attributes attributes) throws SAXException {  
                super.startElement(uri, localName, qName, attributes);  
                System.out  
                        .println("--------------startElement开始执行--------------------------");  
                System.out.println("uri:::" + uri);  
                System.out.println("localName:::" + localName);  
                System.out.println("qName:::" + qName);  
                for (int i = 0; i < attributes.getLength(); i++) {  
                    String value = attributes.getValue(i);// 获取属性的value值  
                    System.out.println(attributes.getQName(i) + "-----" + value);  
                }  
                System.out.println("------------------startElement执行完毕---------------------------");  
            }  
      
        }  
    }
    


3.程序运行的结果如下:


通过运行结果,希望你对uri,localName,qName有更加深入的了解.


二.我们通过SAXParserFactory、SAXParser完成,步骤如下(建议使用)

说明:如果只是使用SAXParserFactory、SAXParser他们完成只需要如下3步骤

1.获取sax解析器的工厂对象
SAXParserFactory factory = SAXParserFactory.newInstance();
2.通过工厂对象 SAXParser创建解析器对象
SAXParser saxParser = factory.newSAXParser();
3.通过解析saxParser的parse()方法设定解析的文件和自己定义的事件处理器对象
saxParser.parse(new File("src//sax//sida.xml"), new MyDefaultHandler());

案例:解析出"作者"元素标签中的文本内容

1.需要解析的sida.xml文件

[html]

  1. <?xml version="1.0" encoding="UTF-8"?>  
    <!DOCTYPE 四大名著[  
    <!ELEMENT 四大名著 (西游记,红楼梦)>  
    <!ATTLIST 西游记 id ID #IMPLIED>  
    ]>  
    <四大名著>  
        <西游记 id="x001">  
            <作者>吴承恩</作者>  
        </西游记>  
        <红楼梦 id="x002">  
            <作者>曹雪芹</作者>  
        </红楼梦>  
    </四大名著>
    


2.解析测试类和事件处理器类的实现代码

[java] 

  1. package sax;  
      
    import java.io.File;  
      
    import javax.xml.parsers.SAXParser;  
    import javax.xml.parsers.SAXParserFactory;  
      
    import org.junit.Test;  
    import org.xml.sax.Attributes;  
    import org.xml.sax.SAXException;  
    import org.xml.sax.helpers.DefaultHandler;  
      
    public class SaxTest {  
      
        @Test  
        public void test() throws Exception {  
            // 1.获取sax解析器的工厂对象  
            SAXParserFactory factory = SAXParserFactory.newInstance();  
            // 2.通过工厂对象 SAXParser创建解析器对象  
            SAXParser saxParser = factory.newSAXParser();  
            // 3.通过解析saxParser的parse()方法设定解析的文件和自己定义的事件处理器对象  
            saxParser.parse(new File("src//sax//sida.xml"), new MyDefaultHandler());  
      
        }  
      
        // 自己定义的事件处理器  
        class MyDefaultHandler extends DefaultHandler {  
      
            // 解析标签开始及结束的的标识符  
            boolean isOk = false;  
      
            @Override  
            public void startElement(String uri, String localName, String qName,  
                    Attributes attributes) throws SAXException {  
                super.startElement(uri, localName, qName, attributes);  
                // 当解析作者元素开始的时候,设置isOK为true  
                if ("作者".equals(qName)) {  
                    isOk = true;  
                }  
            }  
      
            @Override  
            public void characters(char[] ch, int start, int length)  
                    throws SAXException {  
                // TODO Auto-generated method stub  
                super.characters(ch, start, length);  
                // 当解析的标识符为true时,打印元素的内容  
                if (isOk) {  
                    System.out.println(new String(ch, start, length));  
                }  
            }  
              
            @Override  
            public void endElement(String uri, String localName, String qName)  
                    throws SAXException {  
                super.endElement(uri, localName, qName);  
                // 当解析作者元素的结束的时候,设置isOK为false  
                if ("作者".equals(qName)) {  
                    isOk = false;  
                }  
            }  
      
        }  
    }
    


3.程序运行结果如下:



原文地址:http://blog.csdn.net/redarmy_chen/article/details/12951649

0
0
查看评论

高效解析XML

作者:Ping Guo、Julie Basu、Mark Scardina和K. Karun 为你的Java应用程序选择合适的XML解析技术 随着XML越来越广泛地被采用,高效解析XML文档也变得越来越重要。高效地解析XML数据非常重要,尤其是对于那些要处理大量数据的应用程序,这种技术尤为重要。不正确...
  • kiOm
  • kiOm
  • 2004-10-25 23:20
  • 3966

快速有效的解析大型XML文件

和老师做研究也快一年了。使我认识比较深的是对XML的解析和图论。由于我们做的试验是通过XML来生成图,于是摆在我们面前的首要问题是如何解析XML。             ...
  • JDream314
  • JDream314
  • 2011-07-20 21:25
  • 8853

c#加载xml的快速高效的算法

private DataSet ConvertXmlToDataSet(string xmlPath) { DataSet mySet = new DataSet(); XmlDocument xdoc = new XmlDocument(); ...
  • LanSeTianKong12
  • LanSeTianKong12
  • 2017-06-29 15:11
  • 337

Delphi XE2 XML编程备忘

Delphi XE2内部集成的XML功能 上层: XML.XMLIntf/XMLDoc 中层:XML.XMLDOM 下层:Xml.Win.msxmldom、Xml.adomxmldom 底层:Winapi.msxml、Xml.Internal.AdomCore   遗憾:XML...
  • c5soft
  • c5soft
  • 2013-01-10 08:43
  • 1075

XPath快速解析XML

为什么要使用XPATH,上一篇博客查询越靠近下面单词,时间会越长,超过2s就不太好了,XPAth就是用来提高解析XML速度的。还可以解析html,效率也是不错的! 分别查询下列信息 代码: <?php // 详细学习可以参考w3cschool 构造一个XPATH查询器 $xml = ...
  • buyingfei888
  • buyingfei888
  • 2014-11-22 16:26
  • 1255

XML基础+Java解析XML +几种解析方式的性能比较

XML基础+Java解析XML 一:XML基础 XML是什么: 可扩展的标记语言 XML能干什么: 描述数据、存储数据、传输(交换)数据。 XML与HTML区别: 目的不一样 XML 被设计用来描述数据,其焦点是数据的内容。 HTML 被设计用来展示数据,其焦点是数据的外观。 ...
  • u014352836
  • u014352836
  • 2015-06-26 10:18
  • 2759

XML解析的三种方式

参考:http://blog.csdn.net/liuhe688/article/details/6415593 首先定义一个接口 package com.lei.xml; import java.io.InputStream; import java.util.List; public i...
  • qq_31116683
  • qq_31116683
  • 2016-05-06 16:25
  • 3531

性能最高最稳定的Xml解析SDK库

1   概述 本文档适用于C语言开发人员,文档详细讲述Xml解析器SDK中每个函数的 用法以及源码示例。   2    Xml介绍 参考相关文档。   3    Xml 解析...
  • freeland008
  • freeland008
  • 2017-05-04 17:51
  • 196

用XPath解析XML文件

用XPath解析XML文件 一、XPath         XPath 是一门在 XML 文档中查找信息的语言, 可用来在 XML 文档中对元素和属性进行遍历。        XPath表达式比繁琐的文档对象模...
  • lululove19870526
  • lululove19870526
  • 2016-11-10 15:41
  • 2180

第一次写-如何用SAX高效解析超大XML文件

最近用到xml文件想把它读取之后存到数据库里面,但是在网上找了一些方法,发现不是会出现文件过大导致堆溢出的问题,就是效率太低,几百万条数据需要好几个小时甚至一两天,于是我就捉摸着自己写了一个。是用SAX解析的,存储的数据库为SQLserver2012,最终对于将近3个G包含几百万条数据 的xml文件...
  • xianyucishi
  • xianyucishi
  • 2016-08-10 14:05
  • 2003
    个人资料
    • 访问:39024次
    • 积分:531
    • 等级:
    • 排名:千里之外
    • 原创:17篇
    • 转载:5篇
    • 译文:0篇
    • 评论:2条
    文章分类
    最新评论