`
步行者
  • 浏览: 170163 次
  • 性别: Icon_minigender_1
  • 来自: 武汉
社区版块
存档分类
最新评论

SAX解析XML 之 坏毛豆过滤器

    博客分类:
  • XML
阅读更多

在平时的学习中,一些生动简洁的示例总是能让我们更快更好地接受。

下面介绍一个关于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() 方法,这个方法对事件进行处理。


2
0
分享到:
评论

相关推荐

    SAX解析XML文件实例

    一个项目同时用dom解析和sax解析xml文件貌似会报错,项目框架建一直是用sax和dom4j解析xml文件的。当我用dom解析xml文件。导入包后就报错识别不了xml文件的编码格式。于是做了一个sax解析xml文件的实例

    Sax解析XML文件解析

    2. **内存消耗小**:与DOM解析器(将整个XML结构转化为内存中的树形结构)相比,SAX解析器对内存的需求较少。 3. **实时性**:因为是事件驱动,解析过程可以与数据处理同时进行,提高了程序的响应速度。 **SAX解析...

    Java SAX解析Xml文档Demo

    Java SAX(Simple API for XML)解析器是一种基于事件驱动的XML解析方式,它不将整个XML文档加载到内存中,而是逐行读取,当遇到某个事件(如开始标签、结束标签等)时,会触发相应的事件处理器方法。这种方式节省了...

    Servlet利用SAX解析XML文档

    在处理XML数据时,SAX(Simple API for XML)是一种常见的解析器,它采用事件驱动模型,以流式方式读取XML文档,降低了内存占用,适用于处理大型XML文件。本主题将深入探讨如何在Servlet中利用SAX解析XML文档。 ...

    Sax解析xml文件

    在Android和Java编程中,处理XML文件是常见的任务,而SAX(Simple API for XML)是一种轻量级、事件驱动的XML解析器,它以流式方式读取XML文档,只在需要时解析内容,因此非常适合处理大体积的XML文件。 SAX解析器...

    sax解析xml文件

    相较于DOM(Document Object Model)解析器,SAX解析器占用更少的内存和处理时间,因为它不会一次性加载整个XML文档到内存,而是采用事件驱动的方式逐个处理XML元素。在本项目中,"saxloadxml"应该是实现了一个SAX...

    sax解析xml尤其是获取元素的值或者内容

    - SAX解析器不处理XML的DTD(文档类型定义),如果需要验证XML文档,应考虑使用DOM或StAX解析器。 - SAX解析器不保留XML的结构,只提供事件通知,因此不适合需要回溯或查找元素关系的场景。 - 由于SAX是事件驱动...

    SAX解析XML实例

    与DOM(Document Object Model)解析器不同,SAX并不将整个XML文档加载到内存中形成一个树形结构,而是逐行读取文档,遇到元素、属性等事件时触发相应的回调函数。这种方式对于处理大型XML文档非常有效,因为它节省...

    Servlet利用SAX解析XML文档(新上传的有源码)

    Servlet利用SAX解析XML文档(新上传的有源码)Servlet利用SAX解析XML文档(新上传的有源码)Servlet利用SAX解析XML文档(新上传的有源码)Servlet利用SAX解析XML文档(新上传的有源码)Servlet利用SAX解析XML文档(新上传的有...

    java解析xml数据---sax解析器

    Java解析XML数据主要涉及到的是对XML文档的读取和处理,SAX(Simple API for XML)解析器是一种基于事件驱动的解析方式,适用于处理大型XML文件。与DOM(Document Object Model)解析器不同,SAX不需要一次性加载...

    sax解析xml本地读取xml

    SAX(Simple API for XML)是XML解析器的一种,它采用事件驱动的方式对XML文档进行解析,而不是一次性加载整个文档到内存中,因此在处理大型XML文件时,SAX解析器具有较高的性能和较低的内存消耗。 标题“sax解析...

    android 使用Sax解析XML 源码实例

    使用SAX方式解析XML SAX 是读取和操作 XML 数据的更快速、更轻量的方 法。SAX 允许您在读取文档时处理它,从而不必等待整个文档被存储之后才采取操作。它不涉及 DOM 所必需的开销和概念跳跃。 SAX API是一个基于事件...

    一个关于sax解析xml的demo

    SAX(Simple API for XML)是XML解析的一种方式,它以事件驱动模型来处理XML文档,相比于DOM(Document Object Model)解析,SAX解析器占用更少的内存,更适合处理大型XML文件。 SAX解析的基本原理是读取XML文档,...

    sax解析XML方式的代码及特点

    sax解析XML方式的代码及特点,sax解析XML方式的代码及特点,sax解析XML方式的代码及特点,sax解析XML方式的代码及特点

    sax解析xml

    在Java中,SAX解析器遵循XML规范,当解析XML文档时,会触发一系列的事件,如开始文档、结束文档、开始元素、结束元素等。开发者通过实现ContentHandler接口来处理这些事件。下面我们将深入探讨SAX解析XML的相关知识...

    XML解析之SAX解析DEMO

    本文将深入探讨XML解析中的SAX(Simple API for XML)解析方法,并结合一个具体的Android 4.0网络编程示例进行详细讲解。 SAX解析是一种基于事件驱动的解析方式,它不会一次性加载整个XML文档到内存,而是逐行读取...

    android使用SAX解析xml

    SAX(Simple API for XML)是一种事件驱动的解析器,适用于处理大型XML文档,因为它不需要将整个文档加载到内存中,而是逐行读取,从而节省资源。本篇文章将详细介绍如何在Android环境中使用SAX解析器来处理从网络...

    SAX解析xml文件源码

    开发者需要创建一个实现了SAX解析器回调接口的类,当解析器遇到这些事件时,会调用相应的方法,将XML内容传递给用户代码处理。 **SAX解析的工作流程:** 1. 创建SAX解析器:通过`SAXParserFactory`工厂类获取`...

    SAX解析XML源码

    SAX解析器是一种事件驱动的解析器,它不会一次性加载整个XML文档到内存,而是逐行读取,当遇到XML文档中的元素、属性、文本等时,会触发相应的回调函数。这种方式非常适合处理大型XML文件,因为它可以有效地节省内存...

Global site tag (gtag.js) - Google Analytics