XML 要素の削除方法

先月社会復帰したのですが、ついに仕事で Flex を使うことになりました。

Java と比べると ActionScript での XML 操作は格段に楽になっています。
Java の場合、DOM の実装を選択可能なこともあってか、かならず DocumentBuilder とか Document を経由していかないと、XML 要素を作れなかったのが、ActionScript ならシンタックスシュガーもあって、var element:XML = <foo/> とかでいきなり作れます。Document に関係なく、独立したオブジェクトとして XML 要素を作成できるのは非常に便利です。

XML 操作については、Groovy や ScalaRuby、etc... など、多くの言語が手軽に扱える方法を提供しています。最近の言語にとっては必須の機能なのかもしれません。めんどくさい APIJava とは対象的ですね。


XML 要素に子要素を追加する場合、appendChild メソッドを使うのは Java(というか DOM の仕様) と同じです。ならば、子要素を削除するのも同じで removeChild かと思ったのですが、そんなメソッドはありません*1ActionScript の場合、子要素の削除は delete 演算子を使用します。動的プロパティの削除と同様のメカニズムを使用して XML 要素の削除を実現しているのではないかと。
その影響なのか、delete element.foo.(@name == "bar") のように、要素を検索しその結果のノードを削除するような記述はでき無いようです。delete element.foo[0] のように、要素を明確に指定している上で、削除する必要があるようです。

ここで悩んだのが、要素オブジェクトを変数に保持している状況で、その要素のみを削除する方法です。

var xml:XML = <foo/>;
  : // xml に対して、いろいろ追加とか変更とか
  :
var target:XML = <bar/>;
xml.appendChild(target);
  : // xml に対して、いろいろ追加とか変更とか
  :
// target を xml より削除するには??

上記の例で、target を xml から削除するにはどうすればよいのか?
自分は、以下のように、children と childIndex を使用して削除しました。

delete xml.children()[target.childIndex()];

xml.childred() で xml の子要素一覧を表す XMLList を取得し、target.childIndex() で target が xml の何番目の子要素か取得しています。
あとは [] と delete によって要素を削除できます。

*1:このあたりは JavaScript とは違うみたいですね