XML 圧縮アルゴリズムについての簡単な説明

XML 圧縮アルゴリズムについての簡単な説明

XML 圧縮ユニットテストコード

  1. クラスプログラム {
  2. パブリック静的文字列XML = @" <? xml  バージョン="" 1.0 ""エンコーディング="" utf -16"" ?>  
  3.      <お客様>  
  4. <顧客ID > ALFKI </顧客ID >  
  5. < PO > 9572658 </ PO >  
  6. <住所 アドレスタイプ= ""仕事 "" >  
  7.      <通り>メインストリート 1 番地</通り>  
  8.      <都市>どこでも</都市>  
  9.      <> NJ </>  
  10.      <郵便番号> 08080 </郵便番号>  
  11. </住所>  
  12. <注文>  
  13.      <注文ID > 10966 </注文ID   >  
  14.      <行項目>  
  15.          <製品ID > 37 </製品ID >  
  16.          <単価> 26.50 </単価>  
  17.          <数量> 8 </数量>  
  18.          <説明>グラバッド ラックス</説明>                
  19.      </行項目>  
  20.      <行項目>  
  21.          <製品ID > 56 </製品ID >  
  22.          <単価> 38.00 </単価>  
  23.          <数量> 12 </数量>  
  24.          <説明>アリスおばあちゃんのニョッキ</説明>                
  25.      </行項目>  
  26. </注文>       
  27. </顧客> ";
  28. 静的void Main(文字列[]引数) {
  29. XmlZip zip =新しいXmlZip();
  30.  
  31. byte[] bs = Encoding.UTF8.GetBytes (XML);
  32. Console.WriteLine("元のファイルの長さ: {0}", bs.Length);
  33. メモリストリームms =新しいメモリストリーム();
  34. DeflateStream圧縮された zipStream = new DeflateStream(ms, CompressionMode.Compress, true);
  35. 圧縮されたzipStream.Write(bs, 0, bs.Length);
  36. 圧縮されたzipStream.Close();
  37. Console.WriteLine("Deflate 圧縮された長さ: {0}", ms.Length);
  38.  
  39. zip.Init(XML);
  40.      bs = zip.XmlToBytes (XML);
  41. Console.WriteLine("XML 圧縮長: {0}", bs.Length);
  42. 文字列str = zip.BytesToXml (bs);
  43. Console.WriteLine("復元された長さ: {0}", Encoding.UTF8.GetByteCount(str));
  44. Console.WriteLine(str);
  45.  
  46.  
  47.      ms =新しいMemoryStream();
  48.     圧縮された zipStream新しいDeflateStream(ms, CompressionMode.Compress, true);
  49. 圧縮されたzipStream.Write(bs, 0, bs.Length);
  50. 圧縮されたzipStream.Close();
  51. Console.WriteLine("最初に XML 圧縮を行い、次に Deflate 圧縮後の長さ: {0}", ms.Length);
  52. コンソールのキーを読み取ります。
  53.  
  54. }
  55. }

テスト出力

元のファイルの長さ: 740

圧縮後の長さ: 438

XML圧縮長: 295

修復後の長さ: 727

  1. <? xml  バージョン= "1.0"  エンコーディング= "utf-16" ?>  
  2. <お客様>  
  3.    <顧客ID > ALFKI </顧客ID >  
  4.    < PO > 9572658 </ PO >  
  5.    <住所 住所タイプ= "仕事" >  
  6.      <通り>メインストリート 1 番地</通り>  
  7.      <都市>どこでも</都市>  
  8.      <> NJ </>  
  9.      <郵便番号> 08080 </郵便番号>  
  10.    </住所>  
  11.    <注文>  
  12.      <注文ID > 10966 </注文ID >  
  13.      <行項目>  
  14.        <製品ID > 37 </製品ID >  
  15.        <単価> 26.50 </単価>  
  16.        <数量> 8 </数量>  
  17.        <説明>グラバッド ラックス</説明>                
  18.      </行項目>  
  19.      <行項目>  
  20.        <製品ID > 56 </製品ID >  
  21.        <単価> 38.00 </単価>  
  22.        <数量> 12 </数量>  
  23.        <説明>アリスおばあちゃんのニョッキ</説明>                
  24.      </LineItem>  
  25.    </注文>  
  26. </顧客>  

XML 圧縮および Deflate 圧縮後の長さ: 357

XML 圧縮後のデータは、元のデータの約 3 分の 1 であることがわかります。圧縮率は他の独自の圧縮アルゴリズムほど高くないかもしれませんが、効果は満足のいくものです。さらに、私のアルゴリズムは比較的汎用的です。通信相手が XML スキーマを知っていれば、または完全なサンプル コードさえあれば、圧縮された通信を実行できます。私は機能テストのみを行っており、パフォーマンス テストは行っていません。まずは私のアイデアを参考にしてください。

完全なコード

一般的な原則は、通信する双方が XML 文書のノード名と属性名の辞書を保持し、送信側は送信時に ushort を使用して元の XML タグと属性名を置き換えます。受信側は辞書を介して ushort を元の要素名と属性名に変換し、不要な重複タグを大量に排除します。

このコードはこの記事で例としてのみ使用されています。コードはカジュアルに書かれており、防御力や堅牢性はありません。

  1. 内部列挙型 ItemType {
  2. 要素、
  3. アトリチューブ
  4. }
  5. 内部クラス XmlNodeItem {
  6. パブリック文字列 Xpath { 取得; 設定; }
  7. パブリック文字列テキスト { 取得; 設定; }
  8. パブリック ItemType アイテムタイプ { 取得; 設定; }
  9. パブリックオーバーライド文字列ToString() {
  10. Xpath を返します。
  11. }
  12. }
  13. 内部クラス MyXpath {
  14. リンクリスト<文字列>   _node =新しいLinkedList <文字列> ();
  15. パブリック void AddElement(文字列名) {
  16. _node.AddLast(文字列.Format("/{0}", 名前));
  17. }
  18. パブリック void AddAttribute(文字列名) {
  19. _node.AddLast(文字列.Format("/@{0}", 名前));
  20. }
  21. パブリック void RemoveLastElement() {
  22. _node.RemoveLast();
  23. }
  24. パブリックオーバーライド文字列ToString() {
  25. StringBuilder sb =新しいStringBuilder();
  26. LinkedListNode <文字列>  ノード= _node.First ;
  27. sb.Append(ノード.Value);
  28. while ((ノードnode = node.Next) != null) {
  29. sb.Append(ノード.Value);
  30. }
  31. sb.ToString() を返します。
  32. }
  33. }
  34. クラスXmlZip {
  35. 辞書< ushort 、 XmlNodeItem >   _map =新しい辞書< ushort 、XmlNodeItem > ();
  36. 辞書<文字列、ushort >   _map2 =新しい辞書<文字列、 ushort > ();
  37. MyXpath _path =新しいMyXpath();
  38.  
  39. パブリック void Init(文字列 xmlInput) {
  40. StringReader sr =新しいStringReader(xmlInput);
  41. XmlReaderリーダー= XmlReader.Create (sr);
  42. メモリストリームms =新しいメモリストリーム();
  43. ショートi = 1 ;
  44. (reader.Read()) の間 {
  45. スイッチ (リーダー.NodeType) {
  46. XmlNodeType.Elementの場合:
  47. _path.AddElement(リーダー.Name);
  48. _map[i++] = 新しいXmlNodeItem() {
  49.                          Xpath = _path.ToString ()、
  50.                         テキスト= reader.Name
  51.                         アイテムタイプアイテムタイプ= アイテムタイプ.Element
  52. };
  53. (リーダー.HasAttributes)の場合{
  54. リーダー.MoveToFirstAttribute();
  55. _path.AddAttribute(リーダー.Name);
  56. _map[i++] = 新しいXmlNodeItem() {
  57.                              Xpath = _path.ToString ()、
  58.                             テキスト= reader.Name
  59.                             アイテムタイプアイテムタイプ= アイテムタイプ.属性
  60. };
  61. _path.最後の要素を削除します。
  62. (reader.MoveToNextAttribute()) の間 {
  63. _path.AddAttribute(リーダー.Name);
  64. _map[i++] = 新しいXmlNodeItem() {
  65.                                  Xpath = _path.ToString ()、
  66.                                 テキスト= reader.Name
  67.                                 アイテムタイプアイテムタイプ= アイテムタイプ.属性
  68. };
  69. _path.最後の要素を削除します。
  70. }
  71. リーダー.MoveToElement();
  72. }
  73. reader.IsEmptyElement の場合、_path.RemoveLastElement();
  74. 壊す;
  75. XmlNodeType.EndElementの場合:
  76. _path.最後の要素を削除します。
  77. 壊す;
  78. デフォルト:
  79. 壊す;
  80. }
  81. }
  82. foreach (KeyValuePair < ​​ushort 、 XmlNodeItem >ペア in _map) {
  83. _map2[pair.Value.Xpath] = ペア.Key;
  84. }
  85. }
  86.  
  87. パブリック byte[] XmlToBytes(文字列 xmlInput) {
  88. StringReader sr =新しいStringReader(xmlInput);
  89. XmlReaderリーダー= XmlReader.Create (sr);
  90. メモリストリームms =新しいメモリストリーム();
  91. BinaryWriter bw =新しいBinaryWriter(ms);
  92. (reader.Read()) の間 {
  93. ushort インデックス;
  94. バイト[] bs;
  95. スイッチ (リーダー.NodeType) {
  96. XmlNodeType.Elementの場合:
  97. _path.AddElement(リーダー.Name);
  98. if (_map2.TryGetValue(_path.ToString(), 出力インデックス)) {
  99. bw.Write(インデックス);
  100. }
  101. (リーダー.HasAttributes)の場合{
  102. リーダー.MoveToFirstAttribute();
  103. _path.AddAttribute(リーダー.Name);
  104. if (_map2.TryGetValue(_path.ToString(), 出力インデックス)) {
  105. _path.最後の要素を削除します。
  106. bw.Write(インデックス);
  107.                              bs = Encoding.UTF8.GetBytes (リーダー.Value);
  108. bw.Write((ushort)bs.Length);
  109. bw.Write(bs);
  110. }
  111. (reader.MoveToNextAttribute()) の間 {
  112. _path.AddAttribute(リーダー.Name);
  113. if (_map2.TryGetValue(_path.ToString(), 出力インデックス)) {
  114. _path.最後の要素を削除します。
  115. bw.Write(インデックス);
  116.                                  bs = Encoding.UTF8.GetBytes (リーダー.Value);
  117. bw.Write((ushort)bs.Length);
  118. bw.Write(bs);
  119. }
  120. }
  121. リーダー.MoveToElement();
  122. }
  123. (リーダーが空の要素である場合){
  124. _path.最後の要素を削除します。
  125. bw.Write(ushort.MaxValue);
  126. }
  127. 壊す;
  128. XmlNodeType.EndElementの場合:
  129. _path.最後の要素を削除します。
  130. bw.Write(ushort.MaxValue);
  131. 壊す;
  132. XmlNodeType.Textの場合:
  133. bw.Write((ushort)0);
  134.                      bs = Encoding.UTF8.GetBytes (リーダー.Value);
  135. bw.Write((ushort)bs.Length);
  136. bw.Write(bs);
  137. 壊す;
  138. デフォルト:
  139. 壊す;
  140. }
  141. }
  142. bw.Close();
  143. ms.Close();
  144. リーダー.Close();
  145. ms.ToArray() を返します。
  146. }
  147.  
  148. パブリック文字列BytesToXml(byte[] bytes) {
  149. メモリストリームms =新しいメモリストリーム(バイト);
  150. BinaryReader br =新しいBinaryReader(ms);
  151. StringBuilder sb =新しいStringBuilder();
  152. StringWriter sw =新しいStringWriter(sb);
  153. XmlWriterSettings設定=新しいXmlWriterSettings();
  154.         設定.インデント= true ;
  155. XmlWriterライター= XmlWriter .Create(sw, settings);
  156.  
  157. XmlNodeItem 項目;
  158. (br.PeekChar() != -1) の間 {
  159. ushort readFlag = br .ReadUInt16();
  160. 長さ;
  161. バイト[] bs;
  162. 文字列 str;
  163. if (_map.TryGetValue(readFlag, out item)) {
  164. if ( item.ItemType == ItemType.Element)
  165. writer.WriteStartElement(item.Text);
  166. そうでない場合 ( item.ItemType == ItemType.Attritube) {
  167.                      len = br.ReadUInt16 ();
  168.                      bs = br.ReadBytes (len);
  169.                      str = Encoding.UTF8.GetString (bs);
  170. writer.WriteAttributeString(item.Text, str);
  171. }
  172. }
  173. そうでない場合( readFlag == 0){
  174.                  len = br.ReadUInt16 ();
  175.                  bs = br.ReadBytes (len);
  176.                  str = Encoding.UTF8.GetString (bs);
  177. ライター.WriteString(str);
  178. }
  179. そうでない場合 ( readFlag == ushort.MaxValue) {
  180. ライター.WriteEndElement();
  181. }
  182. }
  183. ライターをフラッシュします。
  184. ライター.Close();
  185. sw.Close();
  186. br.閉じる();
  187. sb.ToString() を返します。
  188. }
  189. }

<<:  Java ME での衝突検出アルゴリズムの実装

>>:  SQL Server 2008 のデータ マイニングのための 9 つのアルゴリズム

ブログ    
ブログ    
ブログ    

推薦する

MIT、指の爪ほどの大きさのドローンを作れるマイクロチップを設計

MITの研究者らが、指の爪ほどの小さなドローン用コンピューターチップを設計6月21日、Venture...

...

HDビデオは本物ではなく、数枚の写真でレンダリングされた3Dシーンでは本物かどうか判断が難しい。

今日の紹介を始める前に、次のシナリオを見てみましょう。 上記のアニメーションは、複数の写真からレンダ...

...

今後10年間で、AIは「スモールデータ」時代の到来を告げるでしょうか?

AI 研究に携わる人なら誰でも、データが AI の開発において重要な役割を果たすことをよく知ってい...

生成型人工知能(GenAI)は将来のテクノロジーの展望を一変させる

ChatGPT の人気が高まるにつれ、生成型人工知能 (GenAI) がテクノロジー業界の未来を大き...

概要: インターネット時代です!人工知能に関する4つの大きな誤解

インターネットは現在、非常に急速に発展しており、特に過去2年間で、人工知能はインターネットのトレンド...

なぜ人工知能は高度な数学を解くことができるのでしょうか?

まずは大学院入試から始めましょう。大学院入試の重要性は大学入試の重要性に匹敵します。数字で言うと、2...

...

Google は人工知能の分野で「堀」を持っていないのでしょうか?

少し前、匿名の人物が、Google 社内の研究者による研究メモを Discord プラットフォームに...

Facebook は 10 億枚のソーシャル ソフトウェア写真を使用して新しい AI アルゴリズムをトレーニングします

Facebook の研究者は最近、インターネット上のランダムなラベルなし画像のセットから学習できる新...

Llama-2+Mistral+MPT=? 複数の異種大規模モデルの融合が驚くべき結果を示す

LLaMA や Mistral などの大規模言語モデルの成功により、大手企業やスタートアップ企業は独...

AIの原動力となるディープラーニング

[51CTO.com からのオリジナル記事] 人類が初めてプログラム可能なコンピューターを思いついた...

モバイル写真と人工知能が出会うとき

現在では、カメラ機能はスマートフォンの標準機能となり、スマートフォンの大きなセールスポイントとなって...