在平时的学习中,一些生动简洁的示例总是能让我们更快更好地接受。
下面介绍一个关于SAX 过滤器的应用示例,希望这个示例也对大家有
所帮助
现在厨师要炒毛豆,但是毛豆中有的坏了,我们不能都放在锅里炒吧 ?
当然不能,厨师决定用坏毛豆过滤器把坏毛豆过滤掉,然后再加工毛豆。
先看一下厨房里面的材料吧 :一共有五个毛豆(其中毛豆B,和毛豆D是坏的).
GreenSoyBean.xml
<?xml version="1.0" encoding="GB2312"?>
<材料>
<毛豆 坏的 = 'no'>
A
</毛豆>
<毛豆 坏的 = 'yes'>
B
</毛豆>
<毛豆 坏的 = 'no'>
C
</毛豆>
<毛豆 坏的 = 'no'>
D
</毛豆>
<毛豆 坏的 = 'yes'>
E
</毛豆>
</材料>
坏毛豆过滤器(BadGreenSoyBeanFilter):
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;
import org.xml.sax.helpers.XMLFilterImpl;
import org.xml.sax.helpers.XMLReaderFactory;
/*
* 坏毛豆过滤器,过滤掉所有坏毛豆
*/
public class BadGreenSoyBeanFilter extends XMLFilterImpl {
// 现在查看的毛豆是不是坏毛豆
private boolean currentGreenSoyBeanisBad = false;
public BadGreenSoyBeanFilter() throws SAXException {
super(XMLReaderFactory.createXMLReader());
}
public BadGreenSoyBeanFilter(XMLReader xmlReader) {
super(xmlReader);
}
// 接收文档开始的通知。
@Override
public void startDocument() throws SAXException {
System.out.println("毛豆过滤器 : 准备开始过滤毛豆 。。");
super.startDocument();
}
// 接收文档开始的通知。
@Override
public void endDocument() throws SAXException {
System.out.println("毛豆过滤器 : 毛豆过滤完毕 ");
super.endDocument();
}
// 接收元素的开始的通知。
@Override
public void startElement(String uri, String localName, String qName,
Attributes atts) throws SAXException {
if (localName.equals("毛豆") && atts.getValue("坏的").equals("yes")){
// 现在查看的毛豆是坏毛豆
this.currentGreenSoyBeanisBad = true;
} else {
// 现在查看的毛豆不是坏毛豆,那就交给厨师了 !
super.startElement(uri, localName, qName, atts);
}
}
// 接收元素的结尾的通知。
@Override
public void endElement(String uri, String localName, String qName)
throws SAXException {
if (localName.equals("毛豆") && currentGreenSoyBeanisBad) {
// 坏毛豆被过滤掉了,准备查看下一个毛豆了
this.currentGreenSoyBeanisBad = false;
} else {
super.endElement(uri, localName, qName);
}
}
// 接收字符数据的通知。
@Override
public void characters(char[] ch, int start, int length)
throws SAXException {
StringBuilder stringBuilder = new StringBuilder();
for (int i = start; i < start + length; i++) {
switch (ch[i]) {
case '\r':
break;
case '\t':
break;
case '\n':
break;
default:
stringBuilder.append(ch[i]);
}
}
// 如果现在查看的毛豆是坏毛豆,就把它扔掉
// 否则交给厨师 !
if (this.currentGreenSoyBeanisBad) {
System.out.println("毛豆过滤器 : 扔掉坏毛豆" + stringBuilder.toString());
} else {
super.characters(ch, start, length);
}
}
}
厨师(Chef):
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
public class Chef extends DefaultHandler {
//现在查看的东西是不是毛豆
private boolean isGreenSoyBean = false;
// 接收文档开始的通知。
@Override
public void startDocument() throws SAXException {
System.out.println("厨师 : 准备开始加工毛豆 。。");
}
// 接收文档开始的通知。
@Override
public void endDocument() throws SAXException {
System.out.println("厨师 : 毛豆加工完毕 ");
}
// 接收元素开始的通知。
@Override
public void startElement(String uri, String localName, String qName,
Attributes atts) throws SAXException {
if(localName.equals("毛豆")){
this.isGreenSoyBean = true;
}
}
// 接收元素的结尾的通知。
@Override
public void endElement(String uri,String localName,String qName)
throws SAXException {
if(localName.equals("毛豆")){
this.isGreenSoyBean = false;
}
}
// 接收字符数据的通知。
@Override
public void characters(char[] ch, int start, int length) throws SAXException {
// 现在查看的毛豆是坏毛豆,把它交给厨师 !
if(isGreenSoyBean){
StringBuilder stringBuilder = new StringBuilder();
for(int i = start ; i < start + length ; i++){
switch(ch[i]){
case '\r' : break;
case '\t' : break;
case '\n' : break;
default :stringBuilder.append(ch[i]);
}
}
System.out.println("厨师 : 加工毛豆"+stringBuilder.toString());
}
}
}
开始炒毛豆了。。(先过滤掉所有坏毛豆,再加工剩下的毛豆)
// 创建一个毛豆过滤器
XMLFilter badGreenSoyBeanFilter = new BadGreenSoyBeanFilter();
// 创建一个 毛豆处理器
XMLFilterImpl GreenSoyBeanHandler = new XMLFilterImpl(){
{
// 创建一个加工毛豆的厨师
DefaultHandler chef = new Chef();
// 设置毛豆处理器的 材料加工者 为厨师
this.setContentHandler(chef);
}
};
// 指定工作顺序 :先筛选毛豆,再加工毛豆
GreenSoyBeanHandler.setParent(badGreenSoyBeanFilter);
// 开始筛选和加工毛豆 !
GreenSoyBeanHandler.parse(new InputSource(new FileInputStream("GreenSoyBean.xml")));
下面看看过滤毛豆和加工毛豆的过程吧(控制台输出)
毛豆过滤器 : 准备开始过滤毛豆 。。
厨师 : 准备开始加工毛豆 。。
厨师 : 加工毛豆A
毛豆过滤器 : 扔掉坏毛豆B
厨师 : 加工毛豆C
厨师 : 加工毛豆D
毛豆过滤器 : 扔掉坏毛豆E
毛豆过滤器 : 毛豆过滤完毕
厨师 : 毛豆加工完毕
从输出中我们可以看到,解析XML时产生的事件先由 BadGreenSoyBeanFilter 处理,
BadGreenSoyBeanFilter可以对事件进行过滤,它可以决定是否要将一个事件传给下一个事件处理者(即GreenSoyBeanHandler)。GreenSoyBeanHandler再将接收到的时间进行处理。
看似每个事件最多只被处理过两次,其实不是(只是一些处理过程什么都没做,只是把事件再传了下去)
我们就以其中一个事件(startElement)来说明一下,当解析XML产生 startElement 事件时:
(1)它首先会把事件传给 badGreenSoyBeanFilter 的 starElement() 方法,
这个方法对事件进行过滤,
(2)然后再传给 GreenSoyBeanHandler 的 starElement() 方法
而这个方法什么都不做,
(2)最后再给 GreenSoyBeanHandler.getContentHandler() 的 starElement() 方法
即 Chef 的 starElement() 方法,这个方法对事件进行处理。
分享到:
相关推荐
一个项目同时用dom解析和sax解析xml文件貌似会报错,项目框架建一直是用sax和dom4j解析xml文件的。当我用dom解析xml文件。导入包后就报错识别不了xml文件的编码格式。于是做了一个sax解析xml文件的实例
2. **内存消耗小**:与DOM解析器(将整个XML结构转化为内存中的树形结构)相比,SAX解析器对内存的需求较少。 3. **实时性**:因为是事件驱动,解析过程可以与数据处理同时进行,提高了程序的响应速度。 **SAX解析...
Java SAX(Simple API for XML)解析器是一种基于事件驱动的XML解析方式,它不将整个XML文档加载到内存中,而是逐行读取,当遇到某个事件(如开始标签、结束标签等)时,会触发相应的事件处理器方法。这种方式节省了...
在处理XML数据时,SAX(Simple API for XML)是一种常见的解析器,它采用事件驱动模型,以流式方式读取XML文档,降低了内存占用,适用于处理大型XML文件。本主题将深入探讨如何在Servlet中利用SAX解析XML文档。 ...
在Android和Java编程中,处理XML文件是常见的任务,而SAX(Simple API for XML)是一种轻量级、事件驱动的XML解析器,它以流式方式读取XML文档,只在需要时解析内容,因此非常适合处理大体积的XML文件。 SAX解析器...
相较于DOM(Document Object Model)解析器,SAX解析器占用更少的内存和处理时间,因为它不会一次性加载整个XML文档到内存,而是采用事件驱动的方式逐个处理XML元素。在本项目中,"saxloadxml"应该是实现了一个SAX...
- SAX解析器不处理XML的DTD(文档类型定义),如果需要验证XML文档,应考虑使用DOM或StAX解析器。 - SAX解析器不保留XML的结构,只提供事件通知,因此不适合需要回溯或查找元素关系的场景。 - 由于SAX是事件驱动...
与DOM(Document Object Model)解析器不同,SAX并不将整个XML文档加载到内存中形成一个树形结构,而是逐行读取文档,遇到元素、属性等事件时触发相应的回调函数。这种方式对于处理大型XML文档非常有效,因为它节省...
Servlet利用SAX解析XML文档(新上传的有源码)Servlet利用SAX解析XML文档(新上传的有源码)Servlet利用SAX解析XML文档(新上传的有源码)Servlet利用SAX解析XML文档(新上传的有源码)Servlet利用SAX解析XML文档(新上传的有...
Java解析XML数据主要涉及到的是对XML文档的读取和处理,SAX(Simple API for XML)解析器是一种基于事件驱动的解析方式,适用于处理大型XML文件。与DOM(Document Object Model)解析器不同,SAX不需要一次性加载...
SAX(Simple API for XML)是XML解析器的一种,它采用事件驱动的方式对XML文档进行解析,而不是一次性加载整个文档到内存中,因此在处理大型XML文件时,SAX解析器具有较高的性能和较低的内存消耗。 标题“sax解析...
使用SAX方式解析XML SAX 是读取和操作 XML 数据的更快速、更轻量的方 法。SAX 允许您在读取文档时处理它,从而不必等待整个文档被存储之后才采取操作。它不涉及 DOM 所必需的开销和概念跳跃。 SAX API是一个基于事件...
SAX(Simple API for XML)是XML解析的一种方式,它以事件驱动模型来处理XML文档,相比于DOM(Document Object Model)解析,SAX解析器占用更少的内存,更适合处理大型XML文件。 SAX解析的基本原理是读取XML文档,...
sax解析XML方式的代码及特点,sax解析XML方式的代码及特点,sax解析XML方式的代码及特点,sax解析XML方式的代码及特点
在Java中,SAX解析器遵循XML规范,当解析XML文档时,会触发一系列的事件,如开始文档、结束文档、开始元素、结束元素等。开发者通过实现ContentHandler接口来处理这些事件。下面我们将深入探讨SAX解析XML的相关知识...
本文将深入探讨XML解析中的SAX(Simple API for XML)解析方法,并结合一个具体的Android 4.0网络编程示例进行详细讲解。 SAX解析是一种基于事件驱动的解析方式,它不会一次性加载整个XML文档到内存,而是逐行读取...
SAX(Simple API for XML)是一种事件驱动的解析器,适用于处理大型XML文档,因为它不需要将整个文档加载到内存中,而是逐行读取,从而节省资源。本篇文章将详细介绍如何在Android环境中使用SAX解析器来处理从网络...
开发者需要创建一个实现了SAX解析器回调接口的类,当解析器遇到这些事件时,会调用相应的方法,将XML内容传递给用户代码处理。 **SAX解析的工作流程:** 1. 创建SAX解析器:通过`SAXParserFactory`工厂类获取`...
SAX解析器是一种事件驱动的解析器,它不会一次性加载整个XML文档到内存,而是逐行读取,当遇到XML文档中的元素、属性、文本等时,会触发相应的回调函数。这种方式非常适合处理大型XML文件,因为它可以有效地节省内存...