読者です 読者をやめる 読者になる 読者になる

Flex で条件に合致した XML 要素のみを削除する方法

Flex Flash

Flex 3 で XML の要素や属性を削除するには delete を使用するが、ある条件に合致した全ての要素を一括で delete するスマート方法が見つけられなかった。

使用した環境は以下。

例えば、以下のような XML から price 属性が 100 未満の data 要素を全て削除するような場合。

var itemXml: XML = 
    <itemList>
        <item id="A1" price="100" />
        <item id="B2" price="50">
            <detail>abc</detail>
        </item>
        <item id="C3" price="30" />
        <item id="A2" price="120" />
        <item id="C4" price="80" />
    </itemList>
;

以下のようなコードで実現できるものの、なんかイマイチ。

成功するコード
//price 属性が 100 未満の data 要素を全て削除
var list: XMLList = itemXml.item.(@price < 100);
for (var i: Number = list.length(); i > 0; i--) {
    delete list[i - 1];
}

なお、後ろから消さずに、0 からカウントアップして消していくと C3 のデータが残ってしまうので注意。

処理結果の XML
<itemList>
    <item id="A1" price="100" />
    <item id="A2" price="120" />
</itemList>

本当は以下のようなコードで実現したいものだが、これでは実行時にエラーが発生してしまう。

実行時にエラーが発生するコード
delete itemXml.item.(@price < 100);
エラー内容
TypeError: Error #1119: Delete 演算子はオペランド型 XMLList でサポートされていません。
    at xml_delete2/___xml_delete2_Application1_creationComplete()
    at flash.events::EventDispatcher/dispatchEventFunction()
    at flash.events::EventDispatcher/dispatchEvent()
    at mx.core::UIComponent/dispatchEvent()
    at mx.core::UIComponent/set initialized()
    at mx.managers::LayoutManager/doPhasedInstantiation()
    at Function/http://adobe.com/AS3/2006/builtin::apply()
    at mx.core::UIComponent/callLaterDispatcher2()
    at mx.core::UIComponent/callLaterDispatcher()

ただし、以下のようにして 1件だけ削除する事は可能。

delete itemXml.item.(@price < 100)[0];

ちなみに、以下のようなコードだとコンパイル時にエラーが発生してしまう。

コンパイル時にエラーが発生するコード
for each (var item: XML in itemXml.item.(@price < 100)) {
    delete item;
}
エラー内容
エラー: 固定プロパティ item を削除しようとしています。
削除できるのは、動的に定義されたプロパティだけです。
    delete item;

もっとスマートな書き方は無いのか・・・。