自问世以来的八年间,XML已经流行起来,成为一种开放、半结构化的数据格式,用于保存数据以及通过Web交换数据。由于具有简洁性和易读性,XML在应用开发人员当中备受欢迎,已成为企业架构中必不可少的一部分。
虽然很难列举XML的使用方式有几种,但有一点是可以肯定的::在进行其他操作之前,必须先对XML进行解析。实际上,选择合适的解析器往
往是企业开发人员在项目中必须处理的早期决策之一。而这种决策一次又一次地归结为对两种流行的XML处理模型的选择:文档对象模型(DOM)和用于XML
的简单API(SAX)。
乍一看,DOM和SAX各自的优缺点似乎是互为补充的:DOM在内存中建立对象图;SAX基于事件,内存中不保存任何内容。所以,如果文档很小、数据读取模式很复杂,DOM就是很好的选择,不然,就使用SAX。
不过,实际情况从来没有这么简单。开发人员之所以往往不愿意使用SAX,原因是它很复杂,不过又只好使用它,因为没有其他切实可行的选择。
不然,如果XML文件超过几百KB,DOM的内存开销和性能下降对应用开发人员来说就会成为棘手的绊脚石,这样就无法满足项目对性能的最低要求。
但SAX果真好得多吗?SAX宣称的解析性能(通常比DOM快好几倍)实际上往往带有欺骗性。事实证明,SAX解析具有的笨拙、只向前
(forward-only)的性质不但要求额外的实现工作,而且只要文档结构变得稍稍复杂,性能就会受到影响。如果开发人员决定不对文档进行多次扫描,
就必须缓存文档,或者创建定制的对象模型。
不管怎样,性能都会受到影响,尽管可以通过内部使用SAX来创建更高性能的实现方案,可它仍要创建自己的对象模型,该模型酷似DOM,
结果与其前身(Apache
SOAP)相比,性能几乎没什么提升。此外,SAX与XPath的兼容性也不是很好,通常无法驱动可扩展样式表语言转换(XSLT)处理。所以,SAX解
析绕开了XML处理存在的重大问题。
在寻求比SAX更易使用的替代方案的过程中,越来越多的开发人员求助于用XML的流式API(StAX)。与SAX相比,StAX解析
器可以从XML文件拉取标记,而不是使用回调。虽然它们会显著提高易用性,但还是存在根本问题——StAX的只向前解析方式仍需要繁琐的实现工作以及伴随
而来的隐性性能成本。
因此,任何XML处理模型要具有广泛用途,必须完整呈现XML的层次结构。原因在于,由于XML被设计成通过Web传送复杂数据,所以传送结构信息是XML固有的一项功能。
VTD-XML改变游戏规则
假设我们从头开始使用XML处理来克服DOM和SAX存在的上述问题。新模型可能应当具有以下特性:
● 随机读取功能: 处理模型应当让开发人员可以人工或者使用XPath浏览某种层次结构;
● 高性能: 性能应当远高于DOM和SAX,而性能应当是“切实可靠的”,这意味着性能评测必须包括用于构建层次结构的时间;
● 内存使用少: 为了让处理模型适用于一系列广泛的场合及文件大小,它必须呈现XML的全部结构,同时内存使用数量最少。
为了满足这些目标而设计的VTD-XML是下一代开放源代码XML处理模型,与DOM和SAX相比,它作了根本、全面的改进。VTD-
XML进行优化的一个重要方面就是非提取式标记化(non-extractive
tokenization)。在内部,VTD-XML把原封不动、未解码的XML消息保存在内存中,完全根据名为虚拟标记描述符(VTD)的二进制编码规
范来呈现标记。VTD记录是64位整数,它用XML对标记长度、标记的起始偏移、类型和嵌套深度进行了编码。
关于VTD-XML,最初提出的基本目的是基于专用硬件来移植XML处理,从而使网络交换机和路由器能够高速处理XML内容。这种专用
硬件具体采用现场可编程门阵列(FPGA)或者专用集成电路(ASIC)。后来,VTD-XML项目队伍决定开放VTD-XML的源代码,2004年5月
推出了初期版本:
版本0.5,用Java来实现。自该版本以后,VTD-XML经历了好几轮的改进,因而大大成熟。在版本0.8中,C语言版本VTD-XML和Java版
本VTD-XML一同发布。版本1.0引入了内置的XPath支持功能,于2005年10月发布。最新版本:
版本1.5采用了经过改写的解析引擎,该引擎模块化程度更高、性能更强。
该版本另外还引入了名为缓冲器重用(buffer
reuse)的一项特性。基本思想是,如果位于网络连接后面的XML应用需要重复处理许多进来的XML文档,应用实际上重复使用在第一次处理过程中分配的
内存缓冲器。换句话说,缓冲器分配一次,可以使用多次。VTD-XML所特有的这项特性完全消除了XML处理引起的对象创建及废料收集成本(占DOM和
SAX开销的50%到80%)。VTD-XML项目网站包括最新软件下载及VTD-XML的详细技术介绍。
快速示例
为了感受VTD-XML的编程风格,本文对使用VTD-XML和DOM的代码进行了比较,代码用来解析及浏览简单的XML文件: test.xml,该文件的文本内容显示如下:
< purchaseOrder rderDate="1999-10-21">
< item partNum="872-AA">
< productName>Lawnmower< /productName>
< quantity>1< /quantity>
< USPrice>148.95< /USPrice>
< /item>
< /purchaseOrder>
|
VTD-XML版本样式如下:
import com.ximpleware.*;
import com.ximpleware.parser.*;
import java.io.*;
public class use_vtd {
public static void main(String[] args){
try{
File f = new File("test.xml");
FileInputStream fis = new FileInputStream(f);
byte[] ba = new byte[(int)f.length()];
fis.read(ba);
VTDGen vg = new VTDGen();
vg.setDoc(ba);
vg.parse(false);
VTDNav vn = vg.getNav();
if (vn.matchElement("purchaseOrder")){
System.out.println(" rderDate==>"
+ vn.toString(vn.getAttrVal("orderDate")));
if (vn.toElement(VTDNav.FIRST_CHILD,"item")){
if (vn.toElement(VTDNav.FIRST_CHILD)){
do {
System.out.print( vn.toString(vn.getCurrentIndex()));
System.out.print("==>");
System.out.println( vn.toString(vn.getText()));
} while(vn.toElement(VTDNav.NEXT_SIBLING));
} } } }
catch (Exception e){
System.out.println("exception ccurred ==>"+e);
} } }
|