级别: 中级 Dennis M. Sosnoski (dms@sosnoski.com), Java 和 XML 顾问, Sosnoski Software Solutions, Inc.
2004 年 6 月 01 日 XML 是一种为清晰和易用而设计的文本标记格式,没有考虑简洁性。由于这种设计选择,就文本大小和处理开销而言,文本 XML 的代价可能很高。本文由两部分组成,第 1 部分说明 XML 的替代性非文本表示所涉及到的一些问题,并介绍为此而开发出来的几种方法;第 2 部分将增加一些实际的性能测量数据,以便使您对所能改进的程度有所体会。
将 XML 用于数据交换的不断增长意味着应用程序间发送的 XML 文档的数量和容量也相应地增长。还没有迹象表明这种趋势将来会发生变化,如果说有的话,就是随着基于 XML 的 Web 服务得到越来越广泛的支持和应用,这种增长的速度提高了。取得如此成功毫无疑问说明了 XML 对大量应用程序的适用性。
和任何设计一样,XML 也有一些弱点,其中之一就是把应用程序数据转化成 XML 表示或者相反所需要的开销(无论从大小还是处理时间上来说)。这种开销可能成为许多应用程序总处理代价的主要部分,尤其是那些交换大量数据而内部处理相对较少的应用程序。对于这种类型的应用程序 XML 的很多长处仍然有效,但代价也可能很高。这些代价促使开发人员更深一步考察使用 XML 进行大容量数据交换的权衡问题。
越来越受到关注的一种替代方案是保留 XML 的结构,但为了提高效率采用非本文表示。本文中将讨论 XML 的非文本表示所涉及到的一些问题,并介绍为此目的正在开发的几种方法。第 2 部分将增加一些实际的性能测量数据,以便使您对所能改进的程度有所体会。
文档大小
数据的 XML 表示往往要比相同数据的二进制表示大得多,主要有两个原因:
- 简单数据值的文本表示通常要比相同值的二进制表示大一些。作为一个极端的例子,单字节的二进制值需要用一到四个字符表示一个带符号整数文本值(如“0”、“18”或者“-128”)。
- XML 是为了清晰性和互操作性而不是简洁性设计的一种文本标记格式(如 XML 推荐标准“1.1 Origin and Goals”中指出,“简洁在 XML 标记中最不重要”)。比如说在实践层面上表现为每个起始标签必须有匹配的结束标签。一旦这种冗余与 XML 应用程序中常常使用的相当长的元素和属性名结合起来,XML 文档中标记成分的大小可能远远超出文档中实际数据成分的大小。单纯为了格式化的目的而增加的空白内容(不是 XML 要求的,但是为了 XML 强调的清晰性而常常使用)进一步增加了文档大小。
较大的文档大小意味着传输数据的 XML 表示和等价的二进制表示相比需要更多的带宽。更大的尺寸也意味着更高的处理代价,因为通信过程中涉及到的开销大部分和数据量有关。
处理开销
和简单的二进制数据表示相比,XML 也需要更多的处理开销。从输入端来说,XML 文档处理程序必须识别输入文档文本中代表不同标记形式的多种类型的字符组合。处理程序还需要验证每个文档是结构良好的 XML,因此在处理标记时必须检查状态的转换。名称空间虽然是可选的但其应用越来越普遍,它要求通过相关的前缀跟踪名称空间的定义,并识别和解除引用(dereference)标记中的元素名和属性名所用的前缀。最后,文本 XML 数据可能需要转化成类型化的二进制值,以便接收它的应用程序能够使用。
XML 文档输出也有类似的问题。二进制数据必须首先转化成文本表示。必须对需要用实体表示的字符数据进行检查,必须对各种类型的数据创建标记并添加到输出中。如果使用名称空间,还必须检查标记中所用元素名和属性名的名称空间 URI,并把 URI 转化成适当的前缀。
无论输入还是输出都需要和 XML 文档文本所用的特定字符编码相互转化,进一步增加了复杂性。XML 处理程序通常被设计成能够处理多种不同的可能编码。因此即使两个应用程序间的文档交换总是使用某种预先确定的编码,仍然要付出保证通用性所造成的开销。
跳出文本的框框
XML 仅仅依据文本定义,因此严格地讲文本之外的任何东西都不可能是 XML。另一方面,使用 XML 交换数据的应用程序可能更关心传递的数据,而不是严格的 XML 表示。根据您愿意在多大程度上坚持 XML 的文本特性,可以选择多种不同的技术减少文档大小、提高处理速度或者两者兼备。这一节我将介绍其中的三类技术。
- 一般的文本转换
- 专门为 XML 设计的编码
- 为特定 XML 应用程序量身定做的格式
文本至上:一般的文本转换
最严格遵循 XML 文本特性的技术是一般基于文本的转换。这种类型的转换主要和文档大小有关。文本压缩算法多年来一直是大量研究项目的课题,目前已经非常成熟。这种类型的任何算法都能方便地用于 XML 文档的文本表示。这类算法不大可能改善处理速度,因为实际上在普通的 XML 文本处理之外,它们在应用程序间数据流的两端增加了一层转换:在发送端压缩文本,然后在接收端解压缩。
gzip是一种广泛使用的文本文档压缩算法,在许多平台上都有实现,包括标准的 Java 库。在第 2 部分,我将讨论基于 Java 的性能测试结果,其中包括 gzip 作为一种可选方案。
坚持信仰:为 XML 专门设计编码
在保留文本 XML 文档中真正重要内容的同时,还可以比一般的基于文本的转换更进一步。设计这种类型的方法是为了通过某种编码表示,以能够减少文档大小、降低处理开销或者两方面兼具的方式利用 XML 的结构。从编码形式上重新构造原来的文档,仅仅损失 XML 认为无关的那些信息(因为任何 XML 处理程序通常会忽略这类信息,如属性间的空格数、包围属性值的引号类型以及属性的顺序)通常是可能的。由于损失了信息,原始文档和重新构造的文档进行直接文本比较可能不同,但是对于符合 XML 规则的任何应用程序而言它们是等价的。
我把保留文档 XML 视图的转换称为
XML 编码(XML encoding)。 从 XML 到 XML 编码的转换应该保留任何有效 XML 文档的完整 XML 视图。一般而言这很难证明,不过 XML Canonicalization 推荐标准给出了一种实用性的测试方法:它详细规定了如何把 XML 文档转化成一种标准形式,以便确定文档在逻辑上是否等价,它是很多关于保护和签署 XML 数据的研究项目的基础。当且仅当编码输入文档的规范形式和重新构造的文档的规范形式总能保持一致时,才称这种 XML 数据表示技术是一种 XML 编码,这样说似乎是合理的。如果对于某个合理的文档,该技术不能通过这一测试,就不能认为是一种 XML 编码。
XMill(请参阅
参考资料)是 XML 转换的一个很好的例子,其目的是为了压缩文档的大小。XMill 与 gzip 压缩结合使用,主要是重新安排文档文本使其更容易压缩。其中包括几个步骤:首先用整数代码值代替实际元素的起始和结束标签,单独进行压缩;然后所有元素类型的字符数据组成块单独压缩;对每种类型的元素重复后一个步骤(XMill 也允许定制每种元素类型,但这里先忽略这个问题)。通过用这种方式把类似的数据组织在一起,gzip 可以更有效地操作。最终的结果是以大约相同的处理代价(总起来看甚至更少),得到了比单纯使用 gzip 更小的文档。从描述上看还不很清楚 XMill 是否符合上述意义上的 XML 编码,但无疑能够成为这样一种编码技术。
可以使用其他技术获得比文本 XML 更好的文档处理速度。这些较快的技术通常是通过一个过程减少 XML 文档中的冗余,同时使其更容易处理。这听起来似乎自相矛盾——如果减少了冗余,文档似乎应该更难以处理而不是更容易——但实际上这两个目标可以很好地配合。同时符合两个目标的转换包括用更紧凑的形式置换元素名和属性名,使用计数或者记号代替结束标签,去掉老套的模式(如包围属性值的
="..." 文本),有时候还可以重用重复的字符数据内容值。
我自己的开放源代码项目 XML Binary Infoset(XML 二进制信息集,XBIS,请参阅
参考资料)定义了一种编码技术,其设计目标是保留文档的 XML 视图,把前面所述的各种转换和文档成分的高效压缩字节表示结合起来。 XBIS 的重点是
处理速度而不是文档大小,但通常和文本相比确实能减小文档的大小,同时又提高了处理速度。XBIS 保留了我曾经测试过的所有 XML 文档的规范形式,从这个意义上说,它是一种完整的 XML 编码。(将来也许会发现某些不同寻常的文档破坏了这一条,但如果这样,我会在 XBIS 表式中增加任何被忽视的信息。)
虽然 XBIS 和 XMill 有一些类似之处(包括用数字代码代替元素名),但两者采用了完全不同的方法。XMill 本质上是一种全文档转换(和 gzip 本身一样),就是说必须一次处理文档的全部文本。这意味着需要编码和解码 XMill 表示,因此 XMill(或者单纯的 gzip)在处理系统间传输的文档时可能增加了响应的延迟时间。另一方面,XBIS 是一种流式的转换,编码和解码都是动态完成的。这种区别和 XMill 强调文档大小而 XBIS 强调速度是一致的:如果主要关心大小,增加一些延迟和处理开销把大小降到最低可能是值得的;但是如果主要关心速度,转移的时候尽量减少阻塞的时间通常更好一些。
我个人认为,XML 编码和对文本文档使用 gzip 在逻辑上是等价的。但并非每个人都同意这种观点,对于一些极其崇拜 XML 的开发人员而言,改变文档文本表示的任何形式的转换(即使以和 XML 无关的方式)都是对文档的扭曲。对于这些开发人员而言,允许使用 gzip 是因为它可以重新构造和原始文档完全相同的文本,但不能完全保留文本的任何 XML 编码方法都是不允许的。对于寻求无格式文本或者文本压缩的替代方法的任何项目的开发人员而言,这可能是需要考虑的一个问题。
数据至上:为特定 XML 应用程序量身定做的格式
为特定 XML 应用程序专门设计的格式是和基于文本的压缩相对的另一个极端。这些格式可能和数据的纯二进制表示等价,和文本 XML 相比有可能同时压缩数据的大小并减少处理开销。这种方法的主要缺点是必须根据应用程序使用的文档结构量身定做,发送方和接收方必须事先就具体的结构达成一致,并且实现适当的编码程序/解码程序。
针对应用程序定制编码的多数方法都是基于交换文档的 W3C XML Schema 规范。模式中包含的类型和结构信息用于生成定制的编码程序/解码程序代码,可能包括能够代表文档数据内容并直接与编码程序/解码程序交互的对象。Fast Web Services(请参阅
参考资料)是从模式定制编码的一个例子,它建立在 ASN.1 结构化数据表述的基础上。
这种类型的模式编码很难与处理一般 XML 文档的其他方法比较(类型不一定相同,也不一定有模式)。为了测试各种文档,首先必须为每个文档定义模式,然后生成这种模式的编码程序/解码程序代码。用当前的实现完成这种数据表示和标准 XML 文本形式的转化一般是不可能的,因此还需要编写某种自定义的转化程序,以便把标准文本 XML 文档转化成可以使用这种编码的形式。由于这些原因,我的测试结果中没有包括这种方法的例子,但是在您看过这些结果之后,我还将再提一提模式编码的使用。
结束语
现在我已经介绍了关于为何以及如何使用 XML 的非文本表示的背景,后面将考察这样做所能带来的好处。第 2 部分将说明如何测试一些文档的文本、gzip 和 XBIS 表示。我还将说明和讨论测试的结果,然后看一看这一领域目前正在进行的一些活动。
参考资料
关于作者  | 
|  | Dennis Sosnoski(dms@sosnoski.com)是位于西雅图地区的 Java 咨询公司 Sosnoski Software Solutions, Inc. 的创始人和首席顾问,XML 和 Web 服务培训和咨询专家。Dennis 有 30 多年的专业软件开发经验,最近几年致力于研究服务器端 XML 和 Java 技术。
|
对本文的评价
|