DIV CSS 佈局教程網

 DIV+CSS佈局教程網 >> 網頁腳本 >> XML學習教程 >> XML詳解 >> 壓縮 XML 文件以便有效地傳輸
壓縮 XML 文件以便有效地傳輸
編輯:XML詳解     

關於 XML 的討論中, 二進制 XML的觀點一直不絕於耳。由於其文本傳統,再加上為了對國際化文本的友好性而要求的一些規則,XML 非常冗長。等價的二進制形式要緊湊得多。很久以前(2000 年)的一篇文章“XML The future of EDI?”(請參閱 參考資料)中,我曾經示范了把 ANSI EDI X12 訂單事務(二進制形式)的一部分轉化為 XML。得到的 XML 比原來的 EDI 消息長八倍多(其他一些 XML/EDI 試驗項目的結果似乎只有三倍左右)。這種冗長性給 XML 的存儲帶來了一些問題,但至少在今天存儲器非常便宜。傳輸能力通常受到更大的限制,對二進制 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 文檔

<?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 中聯機傳輸,結果文件通常只有原來的一半大小。這可能足以滿足您在 XML Web 服務中節省空間的需要。如果不能滿足,就好好地看一看 ASN.1。


XML學習教程| jQuery入門知識| AJAX入門| Dreamweaver教程| Fireworks入門知識| SEO技巧| SEO優化集錦|
Copyright © DIV+CSS佈局教程網 All Rights Reserved