ActionScriptでXML形式のファイルを読み込んで利用する際に,ぜひ知っておきたいのが「XPathAPIクラス」です。XPathAPIクラスを利用することで,目的のデータに簡単にアクセスできるようになります。

XMLファイルのデータを抽出

 図1はXMLデータの中から,指定したものだけを抽出して表示するムービーです。このムービーで読み込んでいるXMLファイルは,図2のようなファイルです。

図1:XMLデータを抽出するムービー(クリックするとムービーを表示します)

サンプル・ファイルのダウンロードはこちら

図2:読み込んでいるXMLファイル(クリックすると拡大表示します)

このようにXMLファイルから指定したデータを取り出したい場合には,「XPathAPIクラス」が便利です。

XPath式を使って目的のデータを指定する

 図3は前回も読み込み用に使用したXMLファイルです。このXMLファイルから一つ目の商品の商品名のデータを抜き出すには,

XMLインスタンス.firstChild.firstChild.firstChild.firstChild.nodeValue

のようになんだかとても長くてややこしいステートメントを使う必要がありました。このステートメント,ぱっと一目で見ても,いったい何を抜き出したいのかがよくわかりませんよね*1

図3:読み込みに使用するXMLファイル

 そこで,このステートメントを「XPathAPIクラス」を使ってXPath式で書きなおしてみましょう。

 新規Flashドキュメントを作成し,XMLファイルと同じフォルダ内に適当な名前を付けて保存します。1フレーム目のスクリプトに,XPathAPIを利用しやすいようにimportステートメントを使って次のようにコードを記述します*2

//XPathAPIを使用しやすいようにインポートする
import mx.xpath.XPathAPI

 これで準備はOKです。XPathAPIクラスには,任意のXMLドキュメント・ツリーから,XPath式を使って目的のノードを取り出すために,以下の二つのメソッドが用意されています(表1*3

表1:XPathAPIクラスのメソッド(抜粋)
メソッド説明
selectNodeListメソッドXPath式を満たすノードのリストを返す
selectSingleNodeメソッドXPath式を満たすノードを返す。複数の候補がある場合には,最初に見つかったノードのみを返す

二つのメソッドは,ともにクラスメソッドですので,

XPathAPI.SelectNodeList(引数)
のようにクラス名に続けてメソッド名,引数を記述します。Mathクラスのメソッドと同じですね。

 さて,このselectNodeListメソッドとselectSingleNodeメソッドは,ともに二つの引数を取ります。一つ目の引数は対象となるXMLノードツリー,二つ目の引数はXPath式です。

XPathAPI.selectNodeList(XMLノード,XPath式)
XPathAPI.selectSingleNode (XMLノード,XPath式)

 では,用意したXMLファイルから一つ目の商品の商品名のデータを抜き出してみましょう。サンプルファイルでの「一つ目の商品の商品名」を抜き出すXPath式は「『商品』ノードの『id』属性の値が『1』のノード」ですので,

/データ/商品[@id=1]/商品名
のような形で指定できます。これをselectSingleNodeメソッドを使ってコードに組み込むと,次のようになります。

//XPathAPIを使用できるようにインポートする
import mx.xpath.XPathAPI

var myXML:XML = new XML(); //新規XMLインスタンスの生成 myXML.ignoreWhite = true; //空白を削除して読み込む //イベントハンドラ・メソッドの定義 myXML.onLoad = function() { trace(XPathAPI.selectSingleNode(this.firstChild,"/データ/商品[@id=1]/商品名")); } myXML.load("xmlData.xml"); //XMLファイルを読み込み

 これで一つ目の商品の商品名ノードを抜き出せました(図4)。

図4:XPath式を使ってノードを抜き出した

 二つ目の商品名だけを抜き出したい場合には,「/データ/商品[@id=2]/商品名」,三つ目のみの場合には「/データ/商品[@id=3]/商品名」とすればいいわけですね。これなら見た目にもどんなデータを取り出しているのかが簡単に判別できます。

 また,「あんまん」や「肉まん」等のテキスト・ノードのみを取り出したい場合には,ちょっとお行儀が悪いですけど,「すべてのノード」を表す「*」を使って,

/データ/商品[@id=1]/商品名/*
のようにXPath式を記述すれば,商品名ノードのすべての子ノード(と,いっても「あんまん」や「にくまん」というテキスト・ノード一つしかないのですけれども)を取得し,結果として商品名の文字列のみ*4を抜き出すことができます。

 先ほどのコードで言うならば,onLoadイベントハンドラ・メソッド内を以下のように書き換えれば「肉まん」という文字列を得ることができます(図5)。

myXML.onLoad = function() {
  var n:XMLNode
  var XPathString:String = "/データ/商品[@id=2]/商品名/*"
  n = XPathAPI.selectSingleNode(this.firstChild, XPathString);
  trace(n.nodeValue);
}
図5:文字列のみを抜き出した

XPath式を使って条件を満たすデータを抽出する

 XPathAPIクラスでは,selectNodeListメソッドを使って,条件を満たすノードのリストを得ることもできます。この仕組みを使うと,簡単にデータを抽出できます。

 例えば,図6のようなXMLファイルから,「所属」ノードの値が特定のノードのみを抜き出してみましょう。

図6:抽出を行うXMLファイル

 所属ノードの値が「蜀」の人物ノードのみを抜き出すには,次のようにonLoadイベントハンドラ・メソッドを記述します(図7)。

myXML.onLoad = function() {
  var nodeList:Array;
  var XPathString:String = "/データ/人物[所属=蜀]";
  //条件を満たすノードを配列に格納
  nodeList = XPathAPI.selectNodeList(this.firstChild, XPathString);
  //配列に格納されたノードに対してループ処理
  for (var i:Number = 0 ; i<nodeList.length;i++){
    trace(nodeList[i]);
  }
};

図7:条件を満たすノードのみを抽出

 また,所属が「魏」の人物の「名前」の文字列のみを取り出したい場合には,次のようにXPath式を記述します(図8)。

var XPathString:String = "/データ/人物[所属=魏]/名前/*";
図8:条件を満たすノードの「名前」のみを抽出

 さらに,XPathAPIクラスでは,and式やor式にも対応していますので,「所属」が「魏」か「呉」の人物の名前を抽出したい場合には,次のようにXPath式を記述します(図9)。

var XPathString:String
  = "/データ/人物[所属=魏 or 所属=呉]/名前/*";
図9:OR条件式で抽出したところ

 SQLとまではいきませんが,簡単なデータの抽出ならこれで容易にできてしまいますね。ユーザーが入力/選択した値を元にXPath式を作成すれば,最初のサンプルのように抽出するデータを簡単に切り替えることもできます。

 今回はXPathAPIクラスを利用して,XMLドキュメント・ツリーから目的のデータを簡単に取り出す方法をご紹介しました。これでテキスト・ファイルやXMLファイルを利用して,変化のあるFlashムービーを作成することができますね。

 でも,テキスト・ファイルやXMLファイルを作成して読み込むのは,ちょっと大げさだなあ,ほんのちょっとだけのデータをFlashムービーに渡したいだけなんだけどなあ,なんてケースもあるかもしれません。次回はそんな場合に便利な,HTMLファイルから直接Flashムービーに変数の値を渡して利用する方法をご紹介します。お楽しみに。