当前位置: 首页 > news >正文

使用SAX解析XML

一、        前言

Java解析XML文档,最常用的有两种方法:使用基于事件的XML简单APISimple API for XML)称为SAX和基于树和节点的文档对象模型(Document Object Module)称为DOMSun公司提供了Java API for XML ParsingJAXP)接口来使用SAXDOM,通过JAXP,我们可以使用任何与JAXP兼容的XML解析器。

JAXP接口包含了三个包:

1       org.w 3c .dom  W 3C 推荐的用于XML标准规划文档对象模型的接口。

2       org.xml.sax   用于对XML进行语法分析的事件驱动的XML简单APISAX

3       javax.xml.parsers解析器工厂工具,程序员获得并配置特殊的特殊语法分析器。

二、        前提

DOM编程不要其它的依赖包,因为JDK里自带的JDK里含有的上面提到的org.w 3c .domorg.xml.sax javax.xml.parsers包就可以满意条件了。

三、        使用SAX解析XML文档

SAX是基于事件的简单API,同样的我们也是用一个最简单的例子来看看SAX是如何解析XML

先来看看我们要解析的XML代码吧

<?xml version="1.0" encoding="gb2312"?>

<books>

  <book email="zhoujunhui">

             <name addr="address">rjzjh</name>

             <price>jjjjjj</price>

  </book>

</books>

简单的不能再简单了。但是该有的都有了,根元素、属性、子节点。好了,能反应问题就行了,下面来看看解析这个XML文件的Java代码吧!

1 public class SaxParse {

2     public SaxParse(){

3            SAXParserFactory saxfac=SAXParserFactory.newInstance();

4            try {

5                   SAXParser saxparser=saxfac.newSAXParser();

6                   InputStream is=new FileInputStream("bin/library.xml");

7                   saxparser.parse(is,new MySAXHandler());

8            } catch (ParserConfigurationException e) {

9                   e.printStackTrace();

10           } catch (SAXException e) {

11                  e.printStackTrace();

12           } catch (FileNotFoundException e) {

13                  e.printStackTrace();

14           } catch (IOException e) {

15                  e.printStackTrace();

16           }

17    }

18    public static void main(String[] args) {

19           new SaxParse();

20    }

21  }

这段代码比较短,因为SAX是事件驱动的,它的大部分实现在在另一个Java文件中,先别管另一个文件,我们来一个个地分析吧!

1)得到SAX解析器的工厂实例

3            SAXParserFactory saxfac=SAXParserFactory.newInstance();

这是一个javax.xml.parsers.SAXParserFactory类的实例

2)从SAX工厂实例中获得SAX解析器

5            SAXParser saxparser=saxfac.newSAXParser();

使用javax.xml.parsers.SAXParserFactory工厂的newSAXParser()方法

3)把要解析的XML文档转化为输入流,以便DOM解析器解析它

6                   InputStream is=new FileInputStream("bin/library.xml");

InputStream是一个接口。

4)解析XML文档

7                   saxparser.parse(is,new MySAXHandler());

后面就不用看了,都是些没用的代码(相对而言),够简单的吧!

注意了,我们新建了一个实例new MySAXHandler()这个实例里面又有什么东西呢?

这个实例就是SAX的精华所在。我们使用SAX解析器时,必须实现内容处理器ContentHandler接口中的一些回调方法,然而我们不须要全部地实现这些方法,还好,我们有org.xml.sax.helpers.DefaultHandler类,看它的类申明:

public class DefaultHandler

implements EntityResolver, DTDHandler, ContentHandler, ErrorHandler

实现了这么多接口啊,其它的先不管了,至少它实现了ContentHandler这一接口。

好了,看看这个类有些什么吧?下面是它的Java代码!

public class MySAXHandler extends DefaultHandler {

       boolean hasAttribute=false;

       Attributes attributes=null;

       /* (非 Javadoc

        * @see org.xml.sax.helpers.DefaultHandler#startDocument()

        */

       public void startDocument() throws SAXException {

               System.out.println("文档开始打印了");

       }

       /* (非 Javadoc

        * @see org.xml.sax.helpers.DefaultHandler#endDocument()

        */

       public void endDocument() throws SAXException {

              System.out.println("文档打印结束了");

       }

       /* (非 Javadoc

        * @see org.xml.sax.helpers.DefaultHandler#startElement(java.lang.String, java.lang.String, java.lang.String, org.xml.sax.Attributes)

        */

       public void startElement(String uri, String localName, String qName,

                     Attributes attributes) throws SAXException {

              if(qName.equals("books")){

                     return;

              }

              if(qName.equals("book")){

                     System.out.println(attributes.getQName(0)+attributes.getValue(0));

              }

              if(attributes.getLength()>0){

                     this.attributes=attributes;

                     this.hasAttribute=true;

              }

       }

       /* (非 Javadoc

        * @see org.xml.sax.helpers.DefaultHandler#endElement(java.lang.String, java.lang.String, java.lang.String)

        */

       public void endElement(String uri, String localName, String qName)

                     throws SAXException {

              if(hasAttribute&&(attributes!=null)){

                     for(int i=0;i<attributes.getLength();i++){

                            System.out.println(attributes.getQName(0)+attributes.getValue(0));

                     }

              }

       }

       /* (非 Javadoc

        * @see org.xml.sax.helpers.DefaultHandler#characters(char[], int, int)

        */

       public void characters(char[] ch, int start, int length)

                     throws SAXException {

              System.out.println(new String(ch,start,length));

       }

 

 

}

不要看它一大堆,我一一分解给大家看。我们说SAX是基于事件的API,我们这个类实到了ContentHandler接口中的如下方法:

1startDocument()  用于处理文档解析开始事件

     public void startDocument() throws SAXException {

               System.out.println("文档开始打印了");

        }

2endDocument()  用于处理文档解析结束事件

      public void endDocument() throws SAXException {

              System.out.println("文档打印结束了");

        }

3startElement  用于处理元素开始事件

     public void startElement(String uri, String localName, String qName,

                     Attributes attributes) throws SAXException {

              if(qName.equals("books")){

                     return;

              }

              if(qName.equals("book")){

                     System.out.println(attributes.getQName(0)+attributes.getValue(0));

              }

              if(attributes.getLength()>0){

                     this.attributes=attributes;

                     this.hasAttribute=true;

              }

       }

第二个参数String qName表示这个元素的名字,如:

根节点  <books></books>  它的

相关文章:

  • AJAX实现类Google Suggest效果
  • Android:百度地图 + 百度导航
  • 文章太长了!~关于 XML 的一些基础知识
  • iOS: FFmpeg的使用一
  • ??如何把JavaScript脚本中的参数传到java代码段中
  • HD1285(拓扑排序)
  • 如何用javascript设置延时执行
  • 设计模式--3.模板方法模式
  • 实现JSP数据和JavaScript数据交互使用
  • 使用Apache Xerces解析XML文档
  • 禁ping以及清理系统多余账号说明
  • 使用dom4j和XPath解析XML之例子二
  • [改善Java代码]子列表只是原列表的一个视图
  • 使用Java自带SAX工具解析XML
  • 使用SAX解析XML (控制台程序)
  • 0基础学习移动端适配
  • es6
  • in typeof instanceof ===这些运算符有什么作用
  • JS基础篇--通过JS生成由字母与数字组合的随机字符串
  • LeetCode541. Reverse String II -- 按步长反转字符串
  • RxJS: 简单入门
  • seaborn 安装成功 + ImportError: DLL load failed: 找不到指定的模块 问题解决
  • 包装类对象
  • 聊一聊前端的监控
  • 配置 PM2 实现代码自动发布
  • 使用 @font-face
  • 物联网链路协议
  • Spark2.4.0源码分析之WorldCount 默认shuffling并行度为200(九) ...
  • ​​​​​​​Installing ROS on the Raspberry Pi
  • # include “ “ 和 # include < >两者的区别
  • #我与Java虚拟机的故事#连载11: JVM学习之路
  • #我与Java虚拟机的故事#连载19:等我技术变强了,我会去看你的 ​
  • (2)STL算法之元素计数
  • (LNMP) How To Install Linux, nginx, MySQL, PHP
  • (一)使用Mybatis实现在student数据库中插入一个学生信息
  • (转)C语言家族扩展收藏 (转)C语言家族扩展
  • .net framework 4.0中如何 输出 form 的name属性。
  • .NET 中小心嵌套等待的 Task,它可能会耗尽你线程池的现有资源,出现类似死锁的情况
  • .Net6支持的操作系统版本(.net8已来,你还在用.netframework4.5吗)
  • .NET中GET与SET的用法
  • @Conditional注解详解
  • [2018/11/18] Java数据结构(2) 简单排序 冒泡排序 选择排序 插入排序
  • [Bada开发]初步入口函数介绍
  • [BZOJ2208][Jsoi2010]连通数
  • [bzoj4010][HNOI2015]菜肴制作_贪心_拓扑排序
  • [C#]winform利用seetaface6实现C#人脸检测活体检测口罩检测年龄预测性别判断眼睛状态检测
  • [codevs 2822] 爱在心中 【tarjan 算法】
  • [C进阶] 数据在内存中的存储——浮点型篇
  • [EFI]Dell Inspiron 15 5567 电脑 Hackintosh 黑苹果efi引导文件
  • [element-ui] el-dialog 中的内容没有预先加载,因此无法获得内部元素的ref 的解决方案
  • [Enterprise Library]调用Enterprise Library时出现的错误事件之关闭办法
  • [EWS]查找 文件夹
  • [IDF]聪明的小羊
  • [ISCTF 2023]——Web、Misc较全详细Writeup、Re、Crypto部分Writeup
  • [java]删除数组中的某一个元素