扫一扫
分享文章到微信
扫一扫
关注官方公众号
至顶头条
该模型主要有Parser和Handler两个组件。其原型大体如下:
该模型不规定Handler类型的详细规格,由Parser的实现者根据具体情况而定。
这种模型的核心思想就是由Parser类来具体分析文本的格式,而让信息真正的处理者Handler类从具体的格式中脱离出来,不再需要关心文本物理组织细节。
这种模型仅涉及一个Tokenizer组件。该组件负责将文本分解为一个个token。其原型大体如下:
其中分析的结果以一个结构体TOKEN表示。这个结构体如何设计,同样视具体情况而定。通常它看起来是这样的:
有了Tokenizer,我们就可以轻易的遍历整个文档:
token应当如何划分,其粒度如何,完全取决于设计者的考量。以以下一段xml文本为例:
<elem attr="value">content</elem>
你可以划分为:
也可以将attr-value pair细分为三个token:attr, assign-symbol, value。
你甚至也可以将整个element作为一个token。
从广义上来说,我们文件系统提供的字节流本身已经是一个Tokenizer了,只不过它划分的token是一个个并无多少逻辑含义的character。
而我们后面提到的DOM模型,也可以算是一个Tokenizer。只不过它划分的token只有一个,就是DOM树,与文件系统的字节流走的是另一个极端。
Tokenizer方式与Parse-Handler方式设计思路,最大的不同在于具体处理信息的人主被动地位相异。在Tokenizer模式下,信息处理者调用Tokenizer得到分析数据,如果相邻的token存在上下文关系,你可以根据需要去取得下一个token,故处于主动地位。
而Parse-Handler模式相关死板一些,一方面Handler类实现者才是真正试图处理信息的人,但是实际上对信息的划分(token)却是由Parse规定的,未必完全符合Handler类的需求。另一方面在token存在上下文关系,当前接受的数据信息不足时,Handler类无法随心所欲的取得下一个token(因为从流程上它是被动的数据接受方),而只能暂时缓存数据,等待下一条信息的到来。
DOM模型是最高级的一种模型。它的思路是将文档完整地读入内存,并提供数据访问接口。
DOM模型消耗的内存最多,可提供的服务(我们可以联想一下xml的诸多应用,如xslt等)也最为完整。
这里提到DOM模型消耗的内存最多,这种说法并不全面。例如,在将它与Parse-Handler模型相比时,我们只是计算了Parser的开销,而Handler类是客户实现的,内存开销多少,无从计算。
另一方面,由于DOM模型可以按自己的方式组织数据,它在内存开销上的可优化余地很大,并且客户在使用它时通常不再需要大量的内存分配操作;而Parse-Handler模型中,Handler类的实现者出现蹩脚的设计可能性非常高,计入Handler类的内存开销的话,有时甚至可能远远超过采用DOM模型。
因此我个人认为相对于DOM的能力而言,内存问题在DOM模型中并不算一个了不起的缺陷。实现者可以有很多技巧来进行内存优化。
但是DOM模型有一个问题,就是它一开始就将文档完整的读入了内存,使得它无法胜任那些对响应时间要求较高、希望能够渐进处理的应用。而这一点是采用Parse-Handler模型和Tokenizer模型的好处。
这篇文章写得比较早,因为最近写WINX可视化开发工具相关的设计稿时用到,所以整理了下。我个人在文本文件和各种文档格式的文件打交道较多,多年来也算是形成了一定的经验。我个人现在越来越倾向于采用DOM模型来处理文件。原因在于采用DOM模型有很多优点:
如果您非常迫切的想了解IT领域最新产品与技术信息,那么订阅至顶网技术邮件将是您的最佳途径之一。
现场直击|2021世界人工智能大会
直击5G创新地带,就在2021MWC上海
5G已至 转型当时——服务提供商如何把握转型的绝佳时机
寻找自己的Flag
华为开发者大会2020(Cloud)- 科技行者