ActionScript 3.0で始めるオブジェクト指向スクリプティング

第27回XMLデータを扱う

前回の第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インスタンスに設定して表示
図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 trace()関数でXMLインスタンスのデータが文字列として表示される

それでは、XMLデータから必要な値を指定して、取出す方法について説明しよう。XMLのノードは、ドット演算子(.)でその名前を指定して取出す。得られるノード群のデータ型は、XMLListとする。たとえば、上記XMLインスタンスの<product>ノード群は、つぎのようにノード名を指定して求められる。

var products:XMLList = cs4_xml.product;
trace(products);

取出したノード群のXMLListインスタンスは、trace()関数で図3のように[出力]される。

図3 trace()関数で[出力]されたXMLListインスタンスがもつノード群
図3 trace()関数で[出力]されたXMLListインスタンスがもつノード群

XMLListクラスのインスタンスは、複数ノードのXMLオブジェクトを配列のようにエレメントとしてもつ。配列アクセス演算子[]でインデックスを指定すれば、その位置のノードとなるXMLインスタンスが得られる。たとえば、最初の<product>ノードであれば、そのXMLListインスタンス(products)のインデックス0で取出せる図4⁠。

var first_product:XML = products[0];
trace(first_product);
図4 取出したXMLインスタンスのtrace()関数による[出力]
図4 取出したXMLインスタンスのtrace()関数による[出力]

XMLListインスタンスにノード名をドット演算子(.)で指定して、子ノード群を取出すこともできる。前掲の<product>ノード群のXMLListインスタンスに対してさらに<name>というノード名で、子ノード群が絞り込める図5⁠。

var names:XMLList = products.name;
trace(names);
図5 絞り込まれた子ノード群のXMLListインスタンスをtrace()関数で[出力]
図5 絞り込まれた子ノード群のXMLListインスタンスをtrace()関数で[出力]

また、ノードの要素名を条件にして、子ノード群が選び出せる。条件は、括弧()を使って記述する。たとえば、前掲の<product>ノード群のXMLListインスタンス(products)から<price>要素が699(ドル)の子ノード群は、つぎのようにして得られる。

var products_699:XMLList = products.(price == 699);
trace(products_699);
図6 条件に合った子ノード群のXMLListインスタンスをtrace()関数で[出力]
図6 条件に合った子ノード群のXMLListインスタンスをtrace()関数で[出力]

条件にはノードの属性も使える。指定するときは、属性名の前に@をつける。たとえば、suite属性が"Web"の<product>ノード群を選び出すには、つぎのようなスクリプトを書けばよい。

var products_web:XMLList = products.(@suite == "Web");
trace(products_web);
図7 指定された属性の子ノード群のXMLListインスタンスをtrace()関数で[出力]
図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()関数で[出力]
図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インスタンスに設定して表示
図1(再掲) ロードしたXMLデータから指定の製品名をTextFieldインスタンスに設定して表示

次回は、文字列のパターンの表現である「正規表現」を扱うRegExpクラスについて解説する。

おすすめ記事

記事・ニュース一覧