前回の第26回は「 外部データの読込み待ち 」について説明した。今回は、外部データとしてもよく用いられるXMLデータの扱いだ。ActionScript 3.0におけるXMLの仕様は、「 ECMAScript for XML(E4X)」に準拠する[1] 。なお、本連載ではXML自体の説明は予定していないので、必要があればWebや参考書などで学習してほしい。
外部XMLデータの読込み
まずは、前回の復習も兼ねて、外部XMLファイルを読込んでみよう。用いるのはURLLoaderクラスだ。前回学習したとおり、ロード待ちの処理が必要になる。XMLデータはつぎのように作成して、"adobe_cs4.xml"という名前でFlashムービー(FLA)ファイルと同じ階層に保存しておく。
<?xml version="1.0" encoding="UTF-8"?>
<cs4>
<product suite="Web">
<name>Flash CS4 Professional</name>
<price>699</price>
</product>
<product suite="Web">
<name>Dreamweaver CS4</name>
<price>399</price>
</product>
<product suite="Design">
<name>Photoshop CS4</name>
<price>699</price>
</product>
<product suite="Design">
<name>Illustrator CS4</name>
<price>599</price>
</product>
</cs4>
URLLoaderクラスで外部XMLファイルを読込むフレームアクションは、以下のスクリプト1のとおりだ。ロード待ちまでの構成は、前回のスクリプト2と基本的に変わらない。
スクリプト1 URLLoaderクラスで外部XMLファイルをロードしてTextFieldインスタンスに設定する
// フレームアクション
// フレームアクション
var _txt:TextField = new TextField();
var myLoader:URLLoader = new URLLoader();
var myRequest:URLRequest = new URLRequest("adobe_cs4.xml");
addChild(_txt);
_txt.autoSize = TextFieldAutoSize.LEFT;
_txt.wordWrap = true;
myLoader.addEventListener(Event.COMPLETE, xSetText);
myLoader.load(myRequest);
function xSetText(eventObject:Event):void {
var cs4_xml:XML = XML (myLoader.data); // テキストをXMLデータに変換
// 以下の2行のステートメントについては後述
var product_web:XMLList = cs4_xml.product.(@suite == "Web");
var name_str:String = product_web[0].name.toString();
_txt.text = name_str;
}
外部XMLファイルロードした後、テキストデータをXMLとして解釈する必要がある。それが XML()関数 だ。引数にテキストデータ(文字列)を渡せば、XMLに変換して返す。そのつぎの処理は、XMLデータから、<product>要素のsuite 属性が"Web"のノード群を取出し、その最初(インデックス0)のノードの製品名である<name>要素のテキストを、TextField インスタンスに設定している(図1 ) 。XMLを扱うこの2行のステートメントについては、この後項を改めて解説する。
図1 ロードしたXMLデータから指定の製品名をTextFieldインスタンスに設定して表示
XMLデータから必要な値を取出す
つぎは、XMLデータから必要な値を指定して取出す方法を紹介する。その前に、スクリプトをできるだけシンプルにするため、XMLデータは外部ファイルから読込まず、XMLインスタンスとして生成しよう。
XMLデータはスクリプト上で、つぎのようにタグ(<>)を使って記述する[2] 。変数(プロパティ)や関数(メソッド)から値を取出すのでなく、このように直接プログラムに記述される値を「リテラル」という(第17回「 3D風に回転するアニメーション 」注※4参照) 。データ型の指定はXMLだ。
var cs4_xml:XML =
<cs4>
<product suite="Web">
<name>Flash CS4 Professional</name>
<price>699</price>
</product>
<product suite="Web">
<name>Dreamweaver CS4</name>
<price>399</price>
</product>
<product suite="Design">
<name>Photoshop CS4</name>
<price>699</price>
</product>
<product suite="Design">
<name>Illustrator CS4</name>
<price>599</price>
</product>
</cs4>;
XMLインスタンスをtrace() 関数で[出力]すると、XMLデータの内容がそのまま文字列として表示される(図2 ) 。
図2 trace()関数でXMLインスタンスのデータが文字列として表示される
[2] XMLデータの最後にセミコロン(;)をつけないと、[自動フォーマット]したときにシンタックスエラーになるので注意しよう。もっとも、[シンタックスチェック]してもエラーは出ず、コンパイル(SWFファイルの書出し)も問題なく行われる。
それでは、XMLデータから必要な値を指定して、取出す方法について説明しよう。XMLのノードは、ドット演算子(.)でその名前を指定して取出す。得られるノード群のデータ型は、XMLListとする。たとえば、上記XMLインスタンスの<product>ノード群は、つぎのようにノード名を指定して求められる。
var products:XMLList = cs4_xml.product;
trace(products);
取出したノード群のXMLListインスタンスは、trace() 関数で図3 のように[出力]される。
図3 trace()関数で[出力]されたXMLListインスタンスがもつノード群
XMLListクラス のインスタンスは、複数ノードのXMLオブジェクトを配列のようにエレメントとしてもつ。配列アクセス演算子[]でインデックスを指定すれば、その位置のノードとなるXMLインスタンスが得られる。たとえば、最初の<product>ノードであれば、そのXMLListインスタンス(products)のインデックス0で取出せる(図4 ) 。
var first_product:XML = products[0];
trace(first_product);
図4 取出したXMLインスタンスのtrace()関数による[出力]
XMLListインスタンスにノード名をドット演算子(.)で指定して、子ノード群を取出すこともできる。前掲の<product>ノード群のXMLListインスタンスに対してさらに<name>というノード名で、子ノード群が絞り込める(図5 ) 。
var names:XMLList = products.name;
trace(names);
図5 絞り込まれた子ノード群のXMLListインスタンスをtrace()関数で[出力]
また、ノードの要素名を条件にして、子ノード群が選び出せる。条件は、括弧()を使って記述する。たとえば、前掲の<product>ノード群のXMLListインスタンス(products)から<price>要素が699(ドル)の子ノード群は、つぎのようにして得られる。
var products_699:XMLList = products.(price == 699);
trace(products_699);
図6 条件に合った子ノード群のXMLListインスタンスをtrace()関数で[出力]
条件にはノードの属性も使える。指定するときは、属性名の前に@をつける。たとえば、suite属性が"Web"の<product>ノード群を選び出すには、つぎのようなスクリプトを書けばよい。
var products_web:XMLList = products.(@suite == "Web");
trace(products_web);
図7 指定された属性の子ノード群のXMLListインスタンスをtrace()関数で[出力]
さらに、if ステートメントなどと同じように、条件式は組み合わせてもよい。たとえば、<product>ノード群について、suite属性が"Web"で<price>要素が600(ドル)より高いという指定はつぎのおりだ(図8 ) 。
var products_web:XMLList = products.(@suite == "Web" && price > 600);
trace(products_web);
図8 属性と要素のふたつを条件に取出したの子ノード群のXMLListインスタンスがtrace()関数で[出力]
本稿の結びとして、前項「外部XMLデータの読込み」で掲げたサンプルスクリプト1におけるXMLデータの取出しのステートメントについ、改めて処理内容を確かめよう。
var product_web:XMLList = cs4_xml.product.(@suite == "Web");
var name_str:String = product_web[0].name.toString();
まず、XMLデータ(cs4_xml)の<product>ノードについてsuite属性が"Web"のノード群を、XMLListインスタンス(product_web)として取出している。つぎに、取出した<product>ノード群の最初(インデックス0)のXMLインスタンスから<name>要素を得て、それを文字列に換えているのだ(図1 ) 。
図1(再掲) ロードしたXMLデータから指定の製品名をTextFieldインスタンスに設定して表示
次回は、文字列のパターンの表現である「正規表現」を扱うRegExpクラスについて解説する。