- 浏览: 117893 次
- 来自: ...
文章分类
最新评论
快速与简单并非天生不可兼得, 相反, 简单的东西应该是快速的
在使用 SAX 解析 XML 的过程中, 碰到了以下问题:
- SAX Handler 并没有想象中快, 尤其是文件比较大的时候
- SAX Handler 编写容易出错, 因为需要区别不同的元素, 需要很多判断才能拿到自己想要的信息
- 没有统一的方法获取SAX Handler解析出来的信息
1, Stoppable
缺省情况下SAX Parser会解析整个文件, 即使你已经取得了足够的你想要的信息, 但解析不会停止, 这就是感觉SAX Parser在解析大文件的时候不是很快的原因
只有异常才能阻止SAX Parser继续解析, 所以解决方法很简单:
public interface Stoppable {
boolean canStop();
}
public abstract class EnhancedHandler extends DefaultHandler implements Reportable {
private boolean canStop;
public boolean canStop() { return canStop; }
protected void stop() { canStop = true; } //call this method when subclass objects get enough information.
}
public class CompositeEnhancedHandler extends DefaultHandler {
private static final RuntimeException SHOULD_STOP_EXCEPTION = new ShouldStopParsingException();
private final EnhancedHandler[] handlers;
public CompositeEnhancedHandler(EnhancedHandler... handlers) {
this.handlers = handlers;
}
public void characters(char[] ch, int start, int length) throws SAXException {
for (EnhancedHandler handler : handlers) { handler.characters(ch, start, length); }
throwExceptionIfCanStop();
}
public void endElement(String uri, String localName, String qName) throws SAXException {
for (EnhancedHandler handler : handlers) { handler.endElement(uri, localName, qName); }
throwExceptionIfCanStop();
}
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
for (EnhancedHandler handler : handlers) { handler.startElement(uri, localName, qName, attributes); }
throwExceptionIfCanStop();
}
private void throwExceptionIfCanStop() {
for (EnhancedHandler handler : handlers) { if (!handler.canStop()) { return; } }
throw SHOULD_STOP_EXCEPTION;
}
}
CompositeEnhancedHandler handler = new CompositeEnhancedHandler(new Handler1(), new Handler2());
try {
SAXParser saxParser = SAXParserFactory.newInstance().newSAXParser();
saxParser.parse(new File("england.xml"), handler);
} catch (ShouldStopParsingException se) {
// All handlers got enough information, just stop parsing.
}
2. Subscribable
不能指定只处理特定元素的能力的缺乏, 使得SAX Handler难以编写且易于出错, 不得不判断当前元素的名称, 是否正在处理特定的元素等, 这使得每个Handler都在重复这些逻辑相似的代码.
解决方法是提供一个额外的中间层, 询问SAX Handler对哪个元素感兴趣. 该中间层只会向每个SAX Handler发送它们感兴趣的元素信息. (也可以采用每个SAX Handler向中间层注册感兴趣信息的方法, 但比较复杂, ESAX采用前者)
public interface Subscribable {
String subscribe();
}
b). 中间层 CompositeEnhancedHandler:
public class CompositeEnhancedHandler extends DefaultHandler {
private final AddableMap mapping = new AddableMap();
private List<EnhancedHandler> currentHandlers;
public CompositeEnhancedHandler(EnhancedHandler... handlers) {
... ...
for (EnhancedHandler handler : handlers) { mapping.get(handler.subscribe()).add(handler); }
}
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
currentHandlers = mapping.get(qName);
for (EnhancedHandler handler : currentHandlers) { handler.startElement(uri, localName, qName, attributes); }
... ...
}
for (EnhancedHandler handler : currentHandlers) { handler.characters(ch, start, length); }
... ...
}
public void endElement(String uri, String localName, String qName) throws SAXException {
for (EnhancedHandler handler : currentHandlers) { handler.endElement(uri, localName, qName); }
... ...
}
private static class AddableMap {
private Map<String, List<EnhancedHandler>> container = new HashMap<String, List<EnhancedHandler>>();
public List<EnhancedHandler> get(String qname) {
if (!container.containsKey(qname)) { container.put(qname, new ArrayList<EnhancedHandler>()); }
return container.get(qname);
}
}
}
3. Reportable
DOM提供了很方便的方法供提取特定信息, 但SAX Handler缺失了这项能力, 感兴趣的信息被藏在每个Handler内部
ESAX提供的解决方法是"收集参数模式"
public interface Reportable {
void report(Map resultSet);
}
b). 缺省支持:
public abstract class EnhancedHandler extends DefaultHandler implements Reportable, Stoppable, Subscribable {
... ...
}
public class CompositeEnhancedHandler extends DefaultHandler implements Reportable {
public void report(Map resultSet) {
for (EnhancedHandler handler : handlers) { handler.report(resultSet); }
}
}
最终, ESAX 为 原始的 SAX Handler 补足了 可中止的能力, 可订阅的能力, 可汇报的能力, 使得比原始的SAX Handler更快, 比DOM接口更简单, 更易于编程
一个简单的例子可参见:
http://jade-stone-suite.googlecode.com/svn/trunk/JS.ESax/test/jade/stone/esax/sample/FACupHandler.java
测试用例参见:
http://jade-stone-suite.googlecode.com/svn/trunk/JS.ESax/test/jade/stone/esax/test/CompositeEnhancedHandlerTest.java
最终的缺省实现可参见:
http://jade-stone-suite.googlecode.com/svn/trunk/JS.ESax/src/jade/stone/esax/support/EnhancedHandler.java
http://jade-stone-suite.googlecode.com/svn/trunk/JS.ESax/src/jade/stone/esax/support/CompositeEnhancedHandler.java
项目主页:
http://jade-stone-suite.googlecode.com/svn/trunk/JS.ESax/
发表评论
-
The Object Primer
2004-12-11 11:21 5881,书名 被翻译成“ ... -
错误处理规范
2004-12-11 16:47 757错误处理规范 〇、概念澄清 概念 解释 错误 ... -
Java,误解为何如此之深
2005-08-24 13:50 593前几天被电话面试,问J ... -
Java:画蛇添足的编码规范
2005-09-02 13:13 607前几天公司培训编码规范: 第n条: ... -
synchronized : 规则, 推论与实践
2007-07-23 22:32 46414.3.Synchronization. Rule ... -
交互设计: 股市帮凶
2008-05-04 21:30 642同事 Y 在线操作股票时, 把"买入"点成 ... -
交互设计: 火车上的厕所
2008-05-26 17:17 606有人在动车组的厕所前等了很久, 直到乘务员路过说厕所是被锁住了 ... -
设计原则与模式: 案例介绍--CppUnit
2008-06-01 20:15 613设计原则与模式: 案例介绍--CppUnit CppUnit ... -
工作流:形参,实参,相关数据
2004-12-11 11:40 671关于形参,实参,相关数据 一、形参(FormalParame ... -
工作流:第一次发版,过程总结
2004-12-11 11:42 709交流 即时讨论:小组成员咫尺之遥,有问题立即提出并解决 ... -
工作流:第一次发版,设计总结
2004-12-11 11:43 610整体 面向接口:消息系统,持久系统等,其实现都是可替换 ... -
Beyond Workflow : An Introduction to Vitria BusinessWare
2005-09-26 10:13 803一、简介 Busines ... -
Vitria BusinessWare: 存储与访问安全
2006-03-26 15:45 746事实上,BusinessWare使用LDAP做为存储机制和 ... -
Vitria BusinessWare: 平台与软件总线
2006-04-01 12:59 838经过一段时间的使用 ... -
Vitria BusinessWare: Web Services
2006-04-01 14:30 739BusinessWare的Web Services ... -
Web Services:自洽,编码,交换模型
2006-04-01 16:02 6731, 自洽 以前曾经写过: 目前WebServi ... -
Web Services:WSDL 1.1 规范中的几个错误
2006-04-01 16:40 720读完了WSDL 1.1的规范,令人惊讶的是发现似乎例子中有几个 ... -
C++/CLI:被忽视的集成技术
2006-05-17 20:02 755十几行代码,就使一个重要的旧系统组件,完全融入了基于.Ne ... -
AJP/JK:异构Web平台的集成技术
2006-05-25 21:44 708Tomcat Connector 可以将Tomcat ... -
Vitria BusinessWare: 事件与端口
2006-05-27 17:24 656Event BusinessWare是一个事件驱动的系统 ...
相关推荐
官方离线安装包,测试可用。使用rpm -ivh [rpm完整包名] 进行安装
`laravel-enhanced-exception-handler`可能提供了更友好的错误页面,这些页面不仅对用户友好,还能在开发环境中提供更多的调试信息,如堆栈跟踪和变量值,这对于快速定位问题非常有帮助。 4. **日志记录** 默认的...
yii2-enhanced-gii Yii2 Gii(发电机)与关系 支持 在LinkedIn上支持我 安装 安装此扩展的首选方法是通过 。 无论运行 $ composer require mootensai/yii2-enhanced-gii:dev-master $ composer require kartik-v/...
官方离线安装包,测试可用。使用rpm -ivh [rpm完整包名] 进行安装
凉亭安装要在不声明依赖项的情况下安装: bower install jquery-enhanced-form 如果您希望 Bower 自动将此依赖项添加到您的bower.json ,只需添加--save : bower install --save jquery-enhanced-form 或者您可以...
离线安装包,亲测可用
然而,游戏原版的食物系统相对简单,这激发了开发者的创造力,催生了名为"Enhanced-Food"的模组。这个模组的目标是为Minecraft带来更加丰富和真实的美食体验,让玩家在游戏中享受烹饪和品尝美食的乐趣。 "Enhanced-...
增强蒸汽 增强型Steam是开源的Google Chrome浏览器扩展程序。 请注意,该项目的开发已经结束。 API服务器已于2019年2月1日下线,许多以前可用的功能因此不再可用。 如果您正在寻找Firefox版本,可以在找到它。...
安装此扩展非常简单,用户只需将下载的 "brackets-enhanced-scrollbars-master" 文件解压,然后通过 Brackets 的 "扩展管理器" 功能导入,即可享受到改进后的滚动条效果。在日常开发中,这样的定制化功能对于提升...
免费软件:BSD 2条款许可安装pip install sphinx_py3doc_enhanced_theme将其添加到文档的conf.py : import sphinx_py3doc_enhanced_themehtml_theme = "sphinx_py3doc_enhanced_theme"html_theme_path = [ sphinx_...
5. **兼容性**:作为一款免费插件,Enhanced-Cloudscapes很好地兼容了X-Plane 11,安装简单,用户友好。 在使用Enhanced-Cloudscapes的过程中,玩家可以期待更加沉浸式的飞行体验,无论是长途穿越云海,还是低空...
npm install enhanced-resolve # or Yarn yarn add enhanced-resolve 解决 有一个Node.js API,可以根据Node.js解析规则解析请求。 提供了同步和异步API。 create方法允许创建自定义解析函数。 const resolve = ...
在《JYDGE-Enhanced-Mod》的开发过程中,开发者可能还涉及到了游戏逻辑的调整,比如平衡性改动、新功能的添加以及修复已知问题。这些都需要对游戏的核心机制有深入的理解,并且熟练运用Lua进行编程。 总的来说,...
设置简单 安装软件包: pipenv install django-enhanced-emails 创建一个新的电子邮件类: # myapp/emails.py from enhanced_emails import EnhancedEmail class WelcomeEmail ( EnhancedEmail ): subject = ...
除了Mastodon的通知声音外,您还可以播放每种通知类型的声音。 当前支持的通知类型: 喜爱 促进 回复 回覆(私人) 直接 轮询 跟随 安装 您曾经使用过用户脚本吗? 如果是这样,您可以通过打开进行安装。 如果您...
"ps-enhanced-dde"是一个针对PowerSchool Student Information System(SIS)的定制化解决方案,旨在改进和增强其默认的DDE(Dynamic Data Exchange)和DDA(Data Driven Applications)功能。DDE和DDA是PowerSchool...
Spree Enhanced Banner 还没有作为 gem 分发,所以它应该在你的应用程序中使用 git 引用,或者你可以下载源代码并自己构建 gem。 将以下内容添加到您的 Gemfile 中 gem 'spree_enhanced_banner’, :git => ' ...
这意味着,例如,在Debian GNU / Linux系统上,需要在构建之前安装名称为libssl-dev的软件包: # apt install libssl-dev建造和安装$ cd /path/to/source如果您的系统随附strlcpy()和strlcat()请编辑enhanced-duc-...
"enhanced-lottie"是一个专为Framer X设计的增强型Lottie软件包,它扩展了原生Lottie的功能,提供了对Framer X属性的全面控制。Lottie本身是由Airbnb开发的一个轻量级库,它能够将After Effects创建的动画导出为JSON...
Enhanced-alert一个查询 ui 插件 这个插件用新的替换浏览器对话框(警报、提示、确认)。 用法 警报 $.ea.alert(message[,title[,icon]]) 例子: $.ea.alert("I'm new",'Warning'); 确认 $.ea....