当前位置:  编程技术>java/j2ee

java中使用sax解析xml的解决方法

    来源: 互联网  发布时间:2014-10-24

    本文导语:  在java中,原生解析xml文档的方式有两种,分别是:Dom解析和Sax解析 Dom解析功能强大,可增删改查,操作时会将xml文档以文档对象的方式读取到内存中,因此适用于小文档 Sax解析是从头到尾逐行逐个元素读取内容,修改较为不...

在java中,原生解析xml文档的方式有两种,分别是:Dom解析和Sax解析

Dom解析功能强大,可增删改查,操作时会将xml文档以文档对象的方式读取到内存中,因此适用于小文档

Sax解析是从头到尾逐行逐个元素读取内容,修改较为不便,但适用于只读的大文档

本文主要讲解Sax解析,其余放在后面

Sax采用事件驱动的方式解析文档。简单点说,如同在电影院看电影一样,从头到尾看一遍就完了,不能回退(Dom可来来回回读取)

在看电影的过程中,每遇到一个情节,一段泪水,一次擦肩,你都会调动大脑和神经去接收或处理这些信息

同样,在Sax的解析过程中,读取到文档开头、结尾,元素的开头和结尾都会触发一些回调方法,你可以在这些回调方法中进行相应事件处理

这四个方法是:startDocument() 、 endDocument()、 startElement()、 endElement

此外,光读取到节点处是不够的,我们还需要characters()方法来仔细处理元素内包含的内容

将这些回调方法集合起来,便形成了一个类,这个类也就是我们需要的触发器

一般从Main方法中读取文档,却在触发器中处理文档,这就是所谓的事件驱动解析方法

如上图,在触发器中,首先开始读取文档,然后开始逐个解析元素,每个元素中的内容会返回到characters()方法

接着结束元素读取,所有元素读取完后,结束文档解析

现在我们开始创建触发器这个类,要创建这个类首先需要继承DefaultHandler

创建SaxHandler,并覆写相应方法:

代码如下:

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

 
public class SaxHandler extends DefaultHandler {

    /* 此方法有三个参数
       arg0是传回来的字符数组,其包含元素内容
       arg1和arg2分别是数组的开始位置和结束位置 */
    @Override
    public void characters(char[] arg0, int arg1, int arg2) throws SAXException {
        String content = new String(arg0, arg1, arg2);
        System.out.println(content);
        super.characters(arg0, arg1, arg2);
    }

    @Override
    public void endDocument() throws SAXException {
        System.out.println("n…………结束解析文档…………");
        super.endDocument();
    }

    /* arg0是名称空间
       arg1是包含名称空间的标签,如果没有名称空间,则为空
       arg2是不包含名称空间的标签 */
    @Override
    public void endElement(String arg0, String arg1, String arg2)
            throws SAXException {
        System.out.println("结束解析元素  " + arg2);
        super.endElement(arg0, arg1, arg2);
    }

    @Override
    public void startDocument() throws SAXException {
        System.out.println("…………开始解析文档…………n");
        super.startDocument();
    }

    /*arg0是名称空间
      arg1是包含名称空间的标签,如果没有名称空间,则为空
      arg2是不包含名称空间的标签
      arg3很明显是属性的集合 */
    @Override
    public void startElement(String arg0, String arg1, String arg2,
            Attributes arg3) throws SAXException {
        System.out.println("开始解析元素 " + arg2);
        if (arg3 != null) {
            for (int i = 0; i < arg3.getLength(); i++) {
                 // getQName()是获取属性名称,
                System.out.print(arg3.getQName(i) + "="" + arg3.getValue(i) + """);
            }
        }
        System.out.print(arg2 + ":");
        super.startElement(arg0, arg1, arg2, arg3);
    }
}

XML文档:
代码如下:

 
 
    
      Harry Potter 
      J K. Rowling 
    
    
      Learning XML 
      Erik T. Ray 
    


TestDemo测试类:
代码如下:

import java.io.File;

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

 
public class TestDemo {

    public static void main(String[] args) throws Exception {
        // 1.实例化SAXParserFactory对象
        SAXParserFactory factory = SAXParserFactory.newInstance();
        // 2.创建解析器
        SAXParser parser = factory.newSAXParser();
        // 3.获取需要解析的文档,生成解析器,最后解析文档
        File f = new File("books.xml");
        SaxHandler dh = new SaxHandler();
        parser.parse(f, dh);
    }
}

输出结果:
代码如下:

…………开始解析文档…………

开始解析元素 books
books: 

开始解析元素 book
id="001"book: 

开始解析元素 title
title:Harry Potter
结束解析元素  title

       
开始解析元素 author
author:J K. Rowling
结束解析元素  author

    
结束解析元素  book

    
开始解析元素 book
id="002"book: 

开始解析元素 title
title:Learning XML
结束解析元素  title

       
开始解析元素 author
author:Erik T. Ray
结束解析元素  author

    
结束解析元素  book

 
结束解析元素  books

…………结束解析文档…………

上面的虽然正确显示了执行流程,但是输出却很乱

为了更加清晰的执行此流程,我们还可以重写SaxHandler,使其将原先的xml文档还原一遍

重写的SaxHandler类:

代码如下:

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

 
public class SaxHandler extends DefaultHandler {

    @Override
    public void characters(char[] arg0, int arg1, int arg2) throws SAXException {
        System.out.print(new String(arg0, arg1, arg2));
        super.characters(arg0, arg1, arg2);
    }

    @Override
    public void endDocument() throws SAXException {
        System.out.println("n结束解析");
        super.endDocument();
    }

    @Override
    public void endElement(String arg0, String arg1, String arg2)
            throws SAXException {
        System.out.print("");
        super.endElement(arg0, arg1, arg2);
    }

    @Override
    public void startDocument() throws SAXException {
        System.out.println("开始解析");
        String s = "";
        System.out.println(s);
        super.startDocument();
    }

    @Override
    public void startElement(String arg0, String arg1, String arg2,
            Attributes arg3) throws SAXException {

        System.out.print("");
        super.startElement(arg0, arg1, arg2, arg3);
    }

}

执行结果:

现在看起来好多了,将其还原更能充分说明其解析流程


    
 
 

您可能感兴趣的文章:

  • java 公式解析 表达式解析 expression-analyzer
  • 请问各位:我用SUN公司的JAXP开发包解析XML文档,可不知道对XML解析后如何将结果写回文件中。请各位熟悉Java和XML的高手帮忙。
  • java解析xml之jdom解析xml示例分享
  • Java 的解析器代码生成器 AustenX
  • Java的HTML解析器 Jerry
  • java解析xml之dom4j解析xml示例分享
  • java解析xml之dom解析xml示例分享
  • Java的CSV解析包 CSVBeans
  • Java的CSV解析包 CSVObjects
  • 求教JAVA中XML解析问题
  • Java表达式解析器 JExel
  • Java代码解析工具 JavaFE
  • Java表达式语法解析库 parboiled
  • Java的HTML解析包 jScraper
  • Java的 RSS/Atom的解析器 FeedParser
  • Java的HL7解析器 HAPI
  • java解析xml用什么包?
  • 有什么java包可以支持解析html的。
  • Java结构化数据解析包 Lycia
  • Java的HTML解析库 gohtml
  • Java读写包括中文的txt文件时不同编码格式问题解决
  • 感觉java胜任大型企业级的任务绰绰有余了,可是面对一些小些企业的解决方案听的并不是很多,所以我希望听听各位的看法(如果实际解决过这
  • 请问java中多态性是怎么解决的?
  • java 对树的操作,TreeSet,能否插入相同的数据,如果相同,如何解决
  • Java条形码解决方案 Barbecue
  • Java报表解决方案 OpenReports
  • java.lang.NoclassDefFoundError,怎么解决?
  • 用Java可以解决这个问题吗?急!!!
  • LINUX下的JAVA串口通讯问题,如能解决,不胜感激
  • java中怎样解决汉字乱码问题?
  • 寻找基于JAVA/J2EE的CRM解决方案
  •  
    本站(WWW.)旨在分享和传播互联网科技相关的资讯和技术,将尽最大努力为读者提供更好的信息聚合和浏览方式。
    本站(WWW.)站内文章除注明原创外,均为转载、整理或搜集自网络。欢迎任何形式的转载,转载请注明出处。












  • 相关文章推荐
  • java命名空间java.lang类runtime的类成员方法: runfinalization定义及介绍
  • Java中如何通过方法名动态调用方法?
  • java命名空间java.awt.im类inputcontext的类成员方法: getinputmethodcontrolobject定义及介绍
  • <%@ page import="java.lang.Math"%>后用round(float a)方法,怎么报找不到round方法?
  • java命名空间java.sql类types的类成员方法: java_object定义及介绍
  • java初学--在java中有个native本地方法 说是能嵌入c 不知道具体?
  • java命名空间java.lang类system的类成员方法: runfinalization定义及介绍
  • 在JAVA中只有一种派生子类的方法吗?我记得在C++ 中有3种派生方法的!
  • java命名空间java.lang类stacktraceelement的类成员方法: isnativemethod定义及介绍
  • java根据方法名称取得反射方法的参数类型示例
  • java命名空间java.lang类stacktraceelement的类成员方法: getmethodname定义及介绍
  • 请问java.sql包中 preparedStatement 对象的setString(int parameterIndex,java.lang.String x)方法怎么用?
  • java命名空间java.awt.im.spi接口inputmethod的类成员方法: dispose定义及介绍
  • java.util类对象的DATE方法为何不能用? <%=new java.util.date()%>,在页面中是这样写的,服务器用的是Resin.
  • java命名空间java.net类httpurlconnection的类成员方法: getrequestmethod定义及介绍
  • 有没有一种工具可以让java自动调出类的方法、成员?就像Delphi一样,写完Edit1.系统会跳出一些TEdit的属性、方法。
  • java命名空间java.security类policyspi的类成员方法: enginerefresh定义及介绍
  • 各位高手知道在JAVA中如何用一个名称创建一个对象实例,并调用其方法,注意:在编写代码时并不知要创建的对象的类名,也并不知方法名
  • java命名空间java.awt.im.spi接口inputmethod的类成员方法: getcontrolobject定义及介绍
  • java 与 C++ 实现后绑定的方法
  • java命名空间java.security类policy的类成员方法: refresh定义及介绍
  • 谁能告诉我哪里能找到java包内部类及方法使用介绍
  • java命名空间java.awt.datatransfer类dataflavor的类成员方法: imageflavor定义及介绍
  • 我想学JAVA ,是买THINK IN JAVA 还是JAVA2核心技术:卷1 好???
  • java命名空间java.lang.management类managementfactory的类成员方法: getcompilationmxbean定义及介绍
  • 请问Java高手,Java的优势在那里??,Java主要适合于开发哪类应用程序
  • java命名空间java.lang.management接口runtimemxbean的类成员方法: getlibrarypath定义及介绍
  • 如何将java.util.Date转化为java.sql.Date?数据库中Date类型对应于java的哪个Date呢
  • java命名空间java.lang.management接口runtimemxbean的类成员方法: getstarttime定义及介绍
  • 谁有电子版的《Java编程思想第二版(Thinking in java second)》和《Java2编程详解(special edition java2)》?得到给分
  • java命名空间java.awt.datatransfer类dataflavor的类成员方法: stringflavor定义及介绍


  • 站内导航:


    特别声明:169IT网站部分信息来自互联网,如果侵犯您的权利,请及时告知,本站将立即删除!

    ©2012-2021,,E-mail:www_#163.com(请将#改为@)

    浙ICP备11055608号-3