技巧: 压缩 XML 文件以便有效地传输

前端之家收集整理的这篇文章主要介绍了技巧: 压缩 XML 文件以便有效地传输前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

http://www.ibm.com/developerworks/cn/xml/x-tipcomp.html


如果有很好的压缩方法,何必需要二进制 XML?

二进制 XML 引起了很多讨论,一个诱因是需要相对紧凑的传输格式,尤其是在 Web 服务中的应用。已有的现成解决方案是压缩。这篇技巧说明了如何使用压缩准备在 Web 服务中传输的 XML 文件


关于 XML 的讨论中, 二进制 XML@H_403_20@的观点一直不绝于耳。由于其文本传统,再加上为了对国际化文本的友好性而要求的一些规则,XML 非常冗长。等价的二进制形式要紧凑得多。很久以前(2000 年)的一篇文章“XML The future of EDI?”(请参阅 参考资料)中,我曾经示范了把 ANSI EDI X12 订单事务(二进制形式)的一部分转化为 XML。得到的 XML 比原来的 EDI 消息长八倍多(其他一些 XML/EDI 试验项目的结果似乎只有三倍左右)。这种冗长性给 XML 的存储带来了一些问题,但至少在今天存储器非常便宜。传输能力通常受到更大的限制@H_403_20@,对二进制 XML 最响亮的呼声就来自那些使用 XML 作为消息传输格式的用户包括一些 Web 服务用户

压缩 XML 的一种方法是采用一种针对二进制重新设计的格式。领先的候选对象是 ISO/ITU ASN.1,一种先于 XML 出现的数据传输标准。更新后的 ASN.1 提供了一些和 XML 有关的能力,可以把 XML 格式重新表示成专门的形式,如 ASN.1 Packed Encoding Rules,它定义了一种非常紧凑的二进制编码。OASIS UBL 是其中的一个例子,该计划采用 ASN.1 方法压缩 XML 数据。

压缩 SOAP 编码

如果需要在 Web 服务中传输 XML,您可能会发现有效负载太长了。这种情况下您可以对 XML 内容使用多种文本压缩选项中的一种。清单 1 是前述文章中所提供的那个 XML/EDI 例子。

清单 1. Web 服务交换的示例 XML 文档@H_403_20@

<?xml version="1.0" encoding="UTF-8"?>
<PurchaSEOrder Version="4010">
<PurchaSEOrderHeader>
  <TransactionSetHeader X12.ID="850">
    <TransactionSetIDCode code="850"/>
    <TransactionSetControlNumber>12345</TransactionSetControlNumber>
  </TransactionSetHeader>
  <BeginningSegment>
    <PurposeTypeCode Code="00 Original"/>
    <OrderTypeCode Code="SA Stand-alone Order"/>
    <PurchaSEOrderNumber>RET8999</PurchaSEOrderNumber>
    <PurchaSEOrderDate>19981201</PurchaSEOrderDate>
   </BeginningSegment>
  <AdminCommunicationsContact>
    <ContactFunctionCode Code="OC Order Contact"/>
    <ContactName>Obi Anozie</ContactName>
  </AdminCommunicationsContact>
</PurchaSEOrderHeader>
<PurchaSEOrderDetail>
  <Name1InformationLOOP>
    <Name>
      <EntityIdentifierCode Code="BY Buying Party"/>
      <EntityName>Internet Retailer Inc.</EntityName>
      <IdentificationCodeQualifier Code="91 Assigned by Seller"/>
      <IdentificationCode>RET8999</IdentificationCode>
    </Name>
    <Name>
      <EntityIdentifierCode Code="ST Ship To"/>
      <EntityName>Internet Retailer Inc.</EntityName>
    </Name>
    <AddressInformation>123 Via Way</AddressInformation>
    <GeographicLocation>
      <CityName>Milwaukee</CityName>
      <StateProvinceCode>WI</StateProvinceCode>
      <PostalCode>53202</PostalCode>
    </GeographicLocation>
  </Name1InformationLOOP>
  <BaselineItemData>
    <QuantityOrdered>100</QuantityOrdered>
    <Unit Code="EA Each"/>
    <UnitPrice>1.23</UnitPrice>
    <PriceBasis Code="WE Wholesale Price per Each"/>
    <ProductIDQualifier Code="MG Manufacturer Part Number"/>
    <ProductID Description="Fuzzy Dice">CO633</ProductID>
  </BaselineItemData>
</PurchaSEOrderDetail>
</PurchaSEOrder>

原来的 EDI 例子只有 200 个字节长,而这个 XML 版本有 1721 字节长。

知名的 PK-ZIP 例程能够把这个 XML 文件压缩到 832 个字节。

GNU gzip 例程则把该文件压缩为 707 个字节。

bzip2 中的开发源代码例程把该文件压缩到 748 个字节。

所有这些压缩格式都不如专门的 EDI 格式紧凑,但 EDI 格式不容易理解。bzip2 由于和 gzip 相比对很多文件有更好的压缩效率(在较慢的压缩速度下)而闻名,但是据我的观察上述结果并非个例,就是说对于 XML 的处理 gzip 要好于 bzip2。

目前的多数平台和语言都提供压缩库,至少包含 PK-ZIP 和 GNU gzip 压缩算法,可以在调用 Web 服务之前通过编程进行压缩。

一定要分析标准化(C14N)是否有助于具体实例的压缩。C14N 是生成 XML 文档物理表示——称为标准形式——的标准化方法,以便解决 XML 语法在不改变含义的情况下所允许的细微变化。根据粗略的经验方法,如果 XML 是手工编辑的,属性的顺序和空格的使用可能有各种变化,C14N 可能会改进大型文档的压缩性能。但是如果 XML 是机器生成的或者使用了大量空白元素,C14N 可能是有害的。上述例子更接近后一种情况。我使用 PyXML 项目中的 C14N 模块进行了标准化处理。Python 代码如下所示:

>>> from xml.dom import minidom
>>> from xml.dom.ext import c14n
>>> doc = minidom.parse('listing1.xml')
>>> c14n.Canonicalize(doc)
>>> f = open('listing1-canonical.xml','w')
>>> c14n.Canonicalize(doc,output=f)
>>> f.close()

得到的文件 listing1-canonical.xml 有 1867 个字节,使用 gzip 压缩后还有 714 个字节。未压缩的文本多出了 146 个字节,gzip 压缩后的结果多出了 7 个字节。主要的原因是空白元素在 C14N 之后用最冗长的形式表示。比如,下面这一行:

<Unit Code="EA Each"/>

就变成了

<Unit Code="EA Each"></Unit>

要把 gzip 之类例程压缩后的 XML 绑定到 SOAP 中,有两种办法可供选择:

  • 使用某种形式的附带工具。
  • 对消息主体内容使用 Base64 这样的编码。

Base64 只使用普通的文本字符呈现二进制文档。使用任何平台上准备好的库就可以完成这项工作。Base64 编码数据甚至还有一个 W3C XML Schema,如果正确设置 Web 服务,您的工具就能够自动实现 Base64 的编码和解码操作。不幸的是,Base64 编码部分抵消了压缩效果。Base64 编码要比原来的文档大一些,比例大概是 4:3。使用 Base64 编码后,清单 1 的 gzip 压缩结果是 957 个字节。


结束语

一般说来,如果对 XML 文件应用 gzip,并且压缩后的结果采用 Base64 编码,在 SOAP 中联机传输,结果文件通常只有原来的一半大小@H_403_20@。这可能足以满足您在 XML Web 服务中节省空间的需要。如果不能满足,就好好地看一看 ASN.1。

猜你在找的XML相关文章