E4Xを使ってXMLをマージする

| | Save This Page to del.icio.us このエントリーを含むはてなブックマーク

 最近は必要なデータをなるべくローカル側に持たせるようにしていて、検索などはローカル内だけで行ってしまう場合も少なくなりました。

 ローカル側に必要なデータを全て持たせようとすると結構なボリュームになるので、サーバーからローカルに新しいデータを渡す時は差分だけを渡すようにしています。

 さて、差分を受け取ったローカル側はこれを今あるデータにマージする必要があります。今回はこの処理をE4Xを使って書いてみることにします。

private function merge(data1:XMLList, data2:XMLList):void
{
    var data1Collection:XMLListCollection = new XMLListCollection(data1);
    var data2Collection:XMLListCollection = new XMLListCollection(data2);

    var data2Array:Array = data2Collection.toArray();
    var data2ArrayLength:int = data2Array.length;

    for (var i:int; i < data2ArrayLength; i++) {
        var length:int = data1.(id == data2Array[i].id).length();
        switch (length) {
            case 0:
                data1Collection.addItem(data2Array[i]);
                break;
            case 1:
                data1.(id == data2Array[i].id).setChildren(data2Array[i].children());   
                break;
            default:
                throw new Error('エラー: データフォーマットが正しくありません。');
        }
    }
}

 まず、前提としてデータはidというプライマリーキーを持ったXMLList型のデータということにします。

 

<node>
  <id>1</id>
  <created_at>2008-02-22 12:23:45</created_at>
  <name>吉津 卓保</name>
  <kana>ヨシヅ タクホ</kana>
</node>
<node>
  <id>2</id>
  <created_at>2008-02-22 12:23:45</created_at>
  <name>吉津 卓保</name>
  <kana>ヨシヅ タクホ</kana>
</node>
<node>
  <id>3</id>
  <created_at>2008-02-22 12:23:45</created_at>
  <name>吉津 卓保</name>
  <kana>ヨシヅ タクホ</kana>
</node>
<node>
  <id>4</id>
  <created_at>2008-02-22 12:23:45</created_at>
  <name>吉津 卓保</name>
  <kana>ヨシヅ タクホ</kana>
</node>
<node>
  <id>5</id>
  <created_at>2008-02-22 12:23:45</created_at>
  <name>吉津 卓保</name>
  <kana>ヨシヅ タクホ</kana>
</node>

 data1が現在のデータdata2が新しいデータです。

 E4Xを使うにはXMLList型でなければいけないので、引数ではXMLList型で受けておきます。また、ノードの追加処理をするにはXMLListCollection型が都合が良いので、XMLListCollection型のデータを作ります。さらに、イテレータ処理をするには、Array型が都合が良いのでArray型のデータも作ります。

var data1Collection:XMLListCollection = new XMLListCollection(data1);
var data2Collection:XMLListCollection = new XMLListCollection(data2);

var data2Array:Array = data2Collection.toArray();
var data2ArrayLength:int = data2Array.length;

 E4Xを使って、data1の中からidがdata2のidと一致する数を取得します。

var length:int = data1.(id == data2Array[i].id).length();

 一致するものがなければ追加、一致するものが一つなら新しい値で上書き、一致する物が二個以上あるのは間違っているのでエラーを投げる。

 データは全て参照を渡しているだけなので、XMLList型のもXMLListCollection型のも、Array型のも全て同じデータを指しているのがポイントです。

 ちなみに、Arrayのlengthはプロパティ、XMLListのlengthはメソッド、XMLListCollectionのlengthはプロパティです。この辺り意識しとかないと、気付きにくいバグを作りやすいのでご注意を。

TRACKBACK

このブログ記事を参照しているブログ一覧: E4Xを使ってXMLをマージする

このブログ記事に対するトラックバックURL: http://blog.s2factory.co.jp/MT/mt-tb.cgi/21