- 浏览: 112442 次
- 来自: ...
文章分类
最新评论
快速与简单并非天生不可兼得, 相反, 简单的东西应该是快速的
在使用 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 5561,书名 被翻译成“ ... -
错误处理规范
2004-12-11 16:47 735错误处理规范 〇、概念澄清 概念 解释 错误 ... -
Java,误解为何如此之深
2005-08-24 13:50 568前几天被电话面试,问J ... -
Java:画蛇添足的编码规范
2005-09-02 13:13 554前几天公司培训编码规范: 第n条: ... -
synchronized : 规则, 推论与实践
2007-07-23 22:32 43514.3.Synchronization. Rule ... -
交互设计: 股市帮凶
2008-05-04 21:30 617同事 Y 在线操作股票时, 把"买入"点成 ... -
交互设计: 火车上的厕所
2008-05-26 17:17 583有人在动车组的厕所前等了很久, 直到乘务员路过说厕所是被锁住了 ... -
设计原则与模式: 案例介绍--CppUnit
2008-06-01 20:15 577设计原则与模式: 案例介绍--CppUnit CppUnit ... -
工作流:形参,实参,相关数据
2004-12-11 11:40 636关于形参,实参,相关数据 一、形参(FormalParame ... -
工作流:第一次发版,过程总结
2004-12-11 11:42 674交流 即时讨论:小组成员咫尺之遥,有问题立即提出并解决 ... -
工作流:第一次发版,设计总结
2004-12-11 11:43 583整体 面向接口:消息系统,持久系统等,其实现都是可替换 ... -
Beyond Workflow : An Introduction to Vitria BusinessWare
2005-09-26 10:13 783一、简介 Busines ... -
Vitria BusinessWare: 存储与访问安全
2006-03-26 15:45 719事实上,BusinessWare使用LDAP做为存储机制和 ... -
Vitria BusinessWare: 平台与软件总线
2006-04-01 12:59 786经过一段时间的使用 ... -
Vitria BusinessWare: Web Services
2006-04-01 14:30 712BusinessWare的Web Services ... -
Web Services:自洽,编码,交换模型
2006-04-01 16:02 6261, 自洽 以前曾经写过: 目前WebServi ... -
Web Services:WSDL 1.1 规范中的几个错误
2006-04-01 16:40 693读完了WSDL 1.1的规范,令人惊讶的是发现似乎例子中有几个 ... -
C++/CLI:被忽视的集成技术
2006-05-17 20:02 721十几行代码,就使一个重要的旧系统组件,完全融入了基于.Ne ... -
AJP/JK:异构Web平台的集成技术
2006-05-25 21:44 672Tomcat Connector 可以将Tomcat ... -
Vitria BusinessWare: 事件与端口
2006-05-27 17:24 601Event BusinessWare是一个事件驱动的系统 ...
相关推荐
官方离线安装包,测试可用。使用rpm -ivh [rpm完整包名] 进行安装
yii2-enhanced-gii Yii2 Gii(发电机)与关系 支持 在LinkedIn上支持我 安装 安装此扩展的首选方法是通过 。 无论运行 $ composer require mootensai/yii2-enhanced-gii:dev-master $ composer require kartik-v/...
Laravel开发-enhanced-exception-handler Laravel的增强异常处理程序
离线安装包,亲测可用
官方离线安装包,测试可用。使用rpm -ivh [rpm完整包名] 进行安装
凉亭安装要在不声明依赖项的情况下安装: bower install jquery-enhanced-form 如果您希望 Bower 自动将此依赖项添加到您的bower.json ,只需添加--save : bower install --save jquery-enhanced-form 或者您可以...
增强蒸汽 增强型Steam是开源的Google Chrome浏览器扩展程序。 请注意,该项目的开发已经结束。 API服务器已于2019年2月1日下线,许多以前可用的功能因此不再可用。 如果您正在寻找Firefox版本,可以在找到它。...
免费软件:BSD 2条款许可安装pip install sphinx_py3doc_enhanced_theme将其添加到文档的conf.py : import sphinx_py3doc_enhanced_themehtml_theme = "sphinx_py3doc_enhanced_theme"html_theme_path = [ sphinx_...
npm install enhanced-resolve # or Yarn yarn add enhanced-resolve 解决 有一个Node.js API,可以根据Node.js解析规则解析请求。 提供了同步和异步API。 create方法允许创建自定义解析函数。 const resolve = ...
设置简单 安装软件包: pipenv install django-enhanced-emails 创建一个新的电子邮件类: # myapp/emails.py from enhanced_emails import EnhancedEmail class WelcomeEmail ( EnhancedEmail ): subject = ...
除了Mastodon的通知声音外,您还可以播放每种通知类型的声音。 当前支持的通知类型: 喜爱 促进 回复 回覆(私人) 直接 轮询 跟随 安装 您曾经使用过用户脚本吗? 如果是这样,您可以通过打开进行安装。 如果您...
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-...
强化食品增强Minecraft的美食体验!资料下载目前没有。
Enhanced-alert一个查询 ui 插件 这个插件用新的替换浏览器对话框(警报、提示、确认)。 用法 警报 $.ea.alert(message[,title[,icon]]) 例子: $.ea.alert("I'm new",'Warning'); 确认 $.ea....
括号 - 增强滚动条 这个扩展使滚动条看起来像原生 OS X scollbars,也删除了滚动条的空白间距空间。
:video_game: PSN中文网功能增强插件 :wrench: 功能介绍 :fast_up_button: 全局优化 :crescent_moon: 增加黑夜模式主题选择4。 :gear: 自动黑夜模式2。 :police_officer: 红色高亮特定用户ID(默认高亮管理员)1。...
定位-Magento 2模块增强数量 Magento 2模块在每个数量输入字段旁边添加数量按钮。 使商店的客户更容易增加或减少产品的数量。目录安装通过以下方式安装软件包: composer require siteation/magento...SCSS支持该模块还
jb_enhanced_launchers Arma 3 增强型发射器 Mod 这对香草 RPG 42 火箭进行了改装,使其包含飞越/哨声,并且还对其进行了修改,以允许 AI 对步兵和空中单位使用子弹,当与新声音相结合时,可以在合作中创造更有趣...
增强型Cloudscapes X-Plane 11的免费软件卷云替换插件