Home > action script > xfactorstudioのXPath4AS2の使い方

xfactorstudioのXPath4AS2の使い方

「XPath」という記法自体は、XMLの各要素・属性・テキストにアクセスするための記法としてW3Cが勧告したものですが、このXPath記法をFlashでも使えるようにクラスメソッドを用意してくださったのが、xfactorstudioの「XPath4AS2(エックスパスフォーエイエスツー)」です。

サイト上にはAS1.0用の「XPath4AS」もありますが、今更使わないと思うので、ActionScript2.0に絞って「XPath4AS2」の使い方を書こうと思います。

内容としては、上記W3C勧告のXPathページの「2.5 Abbreviated Syntax」の章、そのページを日本語訳して下さった「どら猫本舗」様のページの内容を参考に、Flashで使えるか試したという感じです。

サンプルzipダウンロード(flashMX2004形式)
(XPathパッケージは含まれていませんので、別途下記より入手ください。)

前準備として、xfactorstudioのサイトからXPath4AS2をダウンロードさせていただき、解凍したフォルダ中のcomフォルダ以下をクラスパス登録(グローバルクラス登録するか、展開したcomフォルダと同じ階層で作業する)しておきます。(当サイトからxpathTestフォルダをダウンロードされた方は、そのフォルダの中にcomフォルダを置いてください。)

制作に入ります。まずは下記のようなxmlファイルを用意します。Shift-JISで作りがちですが、SEPYやFlashの事を考えて、UTF-8で作ります。下記のように文頭でUTF-8宣言した上で、保存時にUTF-8形式で保存して下さい。エディタは「秀丸」など、UTF-8対応エディタで作って下さい。

<?xml version="1.0" encoding="UTF-8"?>
<foods>
	<food category="フルーツ">
		<name>りんご</name>
		<place>青森</place>
		<price>100円</price>
	</food>
	<food category="フルーツ">
		<name>みかん</name>
		<place>愛媛</place>
		<price>80円</price>
	</food>
	<food category="野菜">
		<name>ゴーヤ</name>
		<place>沖縄<city>那覇</city></place>
		<price>70円</price>
	</food>
	<food>
		<name>うどん</name>
		<place>香川</place>
		<price>100円</price>
		<description>ネットで評判のおいしいうどんです。</description>
	</food>
</foods>

上のXML文書をfoodData.xmlとして保存、同じ階層に新規でflaファイルを作成し、ルートの第1フレームに以下のように記述します。

import com.xfactorstudio.xml.xpath.*;

var foodXmlRoot:XML = new XML();
foodXmlRoot.ignoreWhite = true;
foodXmlRoot.onLoad = function(success:Boolean) {
  if (success) {
	//XMLのロードが成功したら、下に定義したxpathTest関数を実行します。
	xpathTest();
  } else {
    trace("XMLのロードに失敗しました。");
  }
};
foodXmlRoot.load("foodData.xml");

xpathクラスパッケージをインポートしておく以外は、普通のXMLロード作業です。phpとの連携の都合等で、どうしてもXML書類がShift-JISな時は、2行目にでも、

System.useCodepage=true;

と入力し、対応して下さい。

今回、XPathのテストは、XMLのロードが成功した時に実行するxpathTest関数の中で定義することにします。先程記述したフレームスクリプト(foodXmlRoot.load…)の下に、xpathTest関数を追加して下さい。XPathの使い方を勉強するための12個のテストを行っています。

//XMLオブジェクトインスタンスfoodXmlRootから、指定したデータを取得し、配列に格納するテスト。
function xpathTest(){
	//test1:ノードを辿って、指定の要素にアクセスする。
	var test1:Array=XPath.selectNodes(foodXmlRoot,"foods/food/name")
	trace(test1);
		//output:<name>りんご</name>,<name>みかん</name>,<name>ゴーヤ</name>,<name>うどん</name>

	//test2:指定の要素中のテキストにアクセスする。
	var test2:Array=XPath.selectNodes(foodXmlRoot,"foods/food/name/text()")
	trace(test2);
		//output:りんご,みかん,ゴーヤ,うどん
		
	//test3:指定の要素の属性にアクセスする。
	var test3:Array=XPath.selectNodes(foodXmlRoot,"foods/food/@category")
	trace(test3);
		//output:フルーツ,フルーツ,野菜
		
	//test4:2番目のfood要素にアクセスする。
	var test4:Array=XPath.selectNodes(foodXmlRoot,"foods/food[2]")
	trace(test4);
		//output:<food category="フルーツ"><name>みかん</name><place>愛媛</place><price>80</price></food>
		
	//test5:最後のfood要素のnameに含まれるテキストにアクセスする。
	var test5:Array=XPath.selectNodes(foodXmlRoot,"foods/food[last()]/name/text()")
	trace(test5);
		//output:うどん
		
	//test6:XML中の全てのprice要素中のテキストにアクセスする。
	var test6:Array=XPath.selectNodes(foodXmlRoot,"//price/text()")
	trace(test6);
		//output:100円,80円,70円,100円
		
	//test7:「..」を使って、ノードをさかのぼっていくこともできます。このテスト自体は無意味ですが、、。
	var test7:Array=XPath.selectNodes(foodXmlRoot,"foods/food[4]/name/../../foods/food[2]/name/text()")
	trace(test7);
		//output:みかん
		
	//test8:food要素の中で、「フルーツ」属性を持つfoodの、name中のテキストにアクセスする。
	var test8:Array=XPath.selectNodes(foodXmlRoot,"//food[@category='フルーツ']/name/text()")
	trace(test8);
		//output:りんご,みかん
		
	//test9:food要素の中で、name要素が「うどん」の値を持つfoodの、price中のテキストにアクセスする。
	var test9:Array=XPath.selectNodes(foodXmlRoot,"//food[name='うどん']/price/text()")
	trace(test9);
		//output:100円
		
	//test10:属性が「フルーツ」のものの2番目の要素の名前にアクセスする。
	var test10:Array=XPath.selectNodes(foodXmlRoot,"//food[@category='フルーツ'][2]/name/text()")
	trace(test10);
		//output:みかん
		
	//test11:description要素を持つfood要素のnameの値にアクセスする。
	var test11:Array=XPath.selectNodes(foodXmlRoot,"//food[description]/name/text()")
	trace(test11);
		//output:うどん
		
	//test12:text()はテキストだけ、node()は内包する全てにアクセスできる。
	var test12_1:Array=XPath.selectNodes(foodXmlRoot,"//food[3]/place/text()")
	var test12_2:Array=XPath.selectNodes(foodXmlRoot,"//food[3]/place/node()")
	trace(test12_1);
	trace(test12_2);
		//output test12_2:沖縄
		//output test12_2:沖縄,<city>那覇</city>
}

重複してしまいますが、test1から解説していきます。

//test1:ノードを辿って、指定の要素にアクセスする。
var test1:Array=XPath.selectNodes(foodXmlRoot,"foods/food/name")
trace(test1);
	//output:<name>りんご</name>,<name>みかん</name>,<name>ゴーヤ</name>,<name>うどん</name>

XPathを使う時はクラスメソッドのXPath.selectNodesを直接呼び出ます。返り値として該当した場所のデータを配列にして返します。式はそれぞれ

var 解析データ格納用Arrayインスタンス名:Array=XPath.selectNodes(解析対象のXMLオブジェクト,"解析対象の指定")

となります。text1の指定方法では<name>タグごと格納されていますね。そこで、

//test2:指定の要素中のテキストにアクセスする。
var test2:Array=XPath.selectNodes(foodXmlRoot,"foods/food/name/text()")
trace(test2);
	//output:りんご,みかん,ゴーヤ,うどん

text()を使う事で、name要素の中のテキストだけを格納できます。こうやって取得した配列「test2」の各要素を取得したり、for文で回したりして使えばよいですね。test2[0]で「りんご」、test2[1]で「みかん」…となります。

//test3:指定の要素の属性にアクセスする。
var test3:Array=XPath.selectNodes(foodXmlRoot,"foods/food/@category")
trace(test3);
	//output:フルーツ,フルーツ,野菜

「@」を使って、属性にもアクセスできます。category属性を設定したのは3カ所なので、3要素だけが出力されます。XMLツリー構造で見ると、foodタグ中に記述されたcategory属性ですが、指定文では「/@…」と、一見下の階層に思いがちなのでご注意ください。

//test4:2番目のfood要素にアクセスする。
	var test4:Array=XPath.selectNodes(foodXmlRoot,"foods/food[2]")
	trace(test4);
		//output:<food category="フルーツ"><name>みかん</name><place>愛媛</place><price>80</price></food>

○番目の要素という指定もできます。ここで注意すべきなのは、xfactorstudioのXPath.selectNodesでは、1番目の要素は[0]ではなく[1]です。Flash標準のXPathやActionScript3のXMLListオブジェクトの指定方法とは異なるのでご注意ください。
test5のように、数字だけでなく、「最後のfood要素」という指定もできます。

//test6:XML中の全てのprice要素中のテキストにアクセスする。
var test6:Array=XPath.selectNodes(foodXmlRoot,"//price/text()")
trace(test6);
	//output:100円,80円,70円,100円

これが大変ありがたいのです。XPath以前のFlashでは、firstChildやchildNodes等を使って、XMLのツリー構造を下っていく作業が面倒でしたが、XPathを使えば、「ツリー構造のどこに存在していようが、price要素を片っ端から配列に突っ込め」という指定ができるのです。これは便利です。
注意点としては、どの階層のprice要素でも取得するので、奥深い階層にたまたま別の使用目的でprice要素(同じ要素名)を作っていたら、そいつも取得し、予期せぬ結果・順番になります。でもまぁ、常識的にXMLを書いていれば、そんなことは滅多にないかと思います。

test7のように、「..」でツリー構造をさかのぼっていく指定もできます。どこで使うかはパッとはイメージできませんが。

//test8:food要素の中で、「フルーツ」属性を持つfoodの、name中のテキストにアクセスする。
var test8:Array=XPath.selectNodes(foodXmlRoot,"//food[@category='フルーツ']/name/text()")
trace(test8);
	//output:りんご,みかん
		
//test9:food要素の中で、name要素が「うどん」の値を持つfoodの、price中のテキストにアクセスする。
var test9:Array=XPath.selectNodes(foodXmlRoot,"//food[name='うどん']/price/text()")
trace(test9);
	//output:100円
		
//test10:属性が「フルーツ」のものの2番目の要素の名前にアクセスする。
var test10:Array=XPath.selectNodes(foodXmlRoot,"//food[@category='フルーツ'][2]/name/text()")
trace(test10);
	//output:みかん

test8,9,10:このあたりもFlashではよく使うかと思います。ユーザーが「フルーツ」を選択したら〜という条件分岐に使えますね。要素中のテキスト、属性のどちらも条件にできます。文字列は「'」で囲って下さい
参考までに、food要素ににtaste属性を追加して

"//food[@category='フルーツ' and @tast='すっぱい']"
とか、
"//food[@category='フルーツ' and name='みかん']/price/text()"

みたいに、andを使って複数条件設定もできます。

//test11:description要素を持つfood要素のnameの値にアクセスする。
var test11:Array=XPath.selectNodes(foodXmlRoot,"//food[description]/name/text()")
trace(test11);
	//output:うどん

のように、特定の要素を持つ親要素だけを探す事もできます。

//test12:text()はテキストだけ、node()は内包する全てにアクセスできる。
var test12_1:Array=XPath.selectNodes(foodXmlRoot,"//food[3]/place/text()")
var test12_2:Array=XPath.selectNodes(foodXmlRoot,"//food[3]/place/node()")
trace(test12_1);
trace(test12_2);
	//output test12_2:沖縄
	//output test12_2:沖縄,<city>那覇</city>

要素中にテキストと子要素が混在している時があれば、この違いを理解しておくとよいですね。

テストファイルをダウンロードして、ご自由にいじってみて、XPathの素晴らしさをご堪能ください。

追記:関数xpathTestの各test配列はローカル変数なので、他の場所から呼び出したい時はスコープをいじってください。

Comment:5

Mi 2007-03-20 (火) 16:35

XPath4AS2の解説、ありがとうございました。
とても役に立ちました。

今回XPathを使用して1万行ほどのXMLを処理したところ、重くなりフリーズ状態になってしまったので限定的に使用することでなんとか回避しました。

tera 2007-03-20 (火) 16:44

お役に立ててよかったです。
>重くなりフリーズ状態
そういえば元同僚の方もそのようなことを言っていました。
膨大なデータを処理する際に、処理はしているのだけれど、画面の全てが止まった状態になるそうで、ローディング表示などができなくて困ったそうです。
僕は実案件で使ったことはないのですが、あんまり使えないのですかねぇ。

Mi 2007-04-03 (火) 10:38

>> 膨大なデータを処理する際に、処理はしているのだけれど、画面の全てが止まった状態になるそうで、ローディング表示などができなくて困った

そうなのです。その状態になってしまいました。
時間がかかるのは問題ないのですが、FlashPlayerがフリーズ状態になってしまうので、大変でした。
次バージョンに期待します。

yamasaki 2007-06-02 (土) 10:25

いつも拝見しています。
このエントリー、わかりやすくて
すごく役にたちました!ありがとうございます。

tera 2007-06-04 (月) 10:53

>yamasaki様
反映遅れてすいません。コメントありがとうございます。
お役に立ててよかったです。
yamasaki様のサイト拝見しました。すごい素敵ですねー。自分も「和」のテイストを考えたことがあったのですが、あんなに素敵なデザインはできませんでした。難しかったです。
今後ともよろしくお願いいたします。

Comment Form

コメントを表示する前にこのブログのオーナーの承認が必要になることがあります。

Remember personal info

Trackback:0

TrackBack URL for this entry
http://www.trick7.com/blog/mt-tb.cgi/327
Listed below are links to weblogs that reference
xfactorstudioのXPath4AS2の使い方 from trick7.com blog

Home > action script > xfactorstudioのXPath4AS2の使い方

持っている Flash & ActionScript 関連本の中から、自分的おすすめの読む順番をご紹介。各書籍のレビューは books カテゴリからご覧頂けます。
この順番でどう?(AS3.0)
  • Adobe Flash CS3 詳細! ActionScript 3.0 入門ノート (DVD付)
    Adobe Flash CS3 詳細! ActionScript 3.0 入門ノート (DVD付)

    デザイン方面からFlashデビューして、そのままAS2.0を使うようになった人が、難しいと評判のAS3デビューする時の最初の1冊として、とにかく目を通しておくと良いかと思います。プログラミング経験の少ない方でも、サンプルをじっくり読めば、ゼロからのAS3デビュー可。
  • ActionScript 3.0 アニメーション
    ActionScript 3.0 アニメーション
    洋書「Making Things Move!」の日本語訳本。ActionScript3.0で数学的アニメーションを作ることがメインテーマなのですが、前半部分でAS3.0の基礎を分かり易く解説されています。後半の重力, IK, 3D表現等のアニメーション解説も楽しい。僕はこれのAS2.0洋書版を読んでFlashの面白さに気付きました。
  • Essential ActionScript 3.0 (Essential)
    Essential ActionScript 3.0 (Essential)

    900ページ以上ある相当分厚い本。基礎からOOPまでを解説。ほぼ網羅しているので、これを抑えておけばAS3博士になれそう。
  • Actionscript 3.0 Cookbook
    Actionscript 3.0 Cookbook

    ActionScript3.0のリファレンス本。問題とその解決法が1ページぐらいで細分化されているので空いた時間にちょっとずつ読み進められる。WebでAS3のソースを見て勉強する時の字引としても使う。ただ、時期的に初期の本なので、AS3自体が仕様変更してたりするので正誤表は必読。
  • Object-Oriented Actionscript 3.0
    Object-Oriented Actionscript 3.0

    7/23に発売されたFlash&OOP本。AS2.0版は持っているのだけど、オブジェクト指向の初歩的な解説から入って、後半は僕の理解を超える難度になっていきました。今度こそ理解できるか?
この順番でどう?(AS2.0)
  • Foundation Actionscript Animation: Making Things Move (Foundation)
    Foundation Actionscript Animation: Making Things Move (Foundation)

    スクリプトでアニメーションさせる方法を学べる。プログラムの知識というよりも数学や物理の知識が必要。バネの表現や3D表現など、汎用性の高いテクニックを身に付けられ、個人の表現力をレベルアップするのに最適。参考までに、僕が調べた英単語リスト。2007年4月に、AS3対応版も発売されました。
  • ゲーム開発のための数学・物理学入門 Beginning Math and Physics for Game Programmers
    ゲーム開発のための数学・物理学入門  Beginning Math and Physics for Game Programmers

    「Making Things Move!」の世界を突き詰めたい人用のステップアップのための本。行列や物理運動、2D/3D表現。Flashの本ではなく、じっくり読むタイプの本なので、あとまわしにしてもいいかも。
  • Flash 8 Essentials
    Flash 8 Essentials

    Flash8の新機能を紹介。全10章が独立した構成で、興味のある部分から読めます。フィルタやビットマップ、ビデオの使い方とかを、基礎から順を追って理解していけるので、ゼロからスクリプティングできるようになる。僕はビットマップ関連の作業の際のリファレンスとして常用しています。
  • .fla―Idea of Flash Creation
    .fla―Idea of Flash Creation

    上の本でFlash8の基本を身に付けて、それをどう面白い表現に落とし込むかを学べます。深津さんの、試行錯誤・実験しやすいスクリプティング、クラス設計に凄さを感じました。YouTubeやFlickrのAPI、PHPとの連携記事も。
  • FLASH ActionScript 2.0入門完全ガイド+実践サンプル集 [CD-ROM付]
    FLASH ActionScript 2.0入門完全ガイド+実践サンプル集 [CD-ROM付]

    ここまでで表現力が付き、テンションが上がるので、その勢いで難解なオブジェクト指向に挑戦。プログラム経験のない人がいきなり英語のOOP本を読むのは厳しい。この本で継承とかインターフェースとかポリモーフィズムとかの用語を理解しておくといいかも。
  • オブジェクト指向でなぜつくるのか―知っておきたいプログラミング、UML、設計の基礎知識―
    オブジェクト指向でなぜつくるのか―知っておきたいプログラミング、UML、設計の基礎知識―

    Flashの本ではありませんが、OOPの概念を気軽に読めるボリュームで解説してくれます。英語と日本語のOOP用語の対応を図るためにも「Object-oriented Actionscript for Flash 8」と併読するのがおすすめ。なんとなく読んでおくだけでも結構違うのでは。
  • Object-oriented Actionscript for Flash 8
    Object-oriented Actionscript for Flash 8

    前半はOOPの利便性や基本の紹介。デザインパターンやMVCの理解。13章からグッと難しくなって大変。Flash8対応。
  • Essential Actionscript 2.0
    Essential Actionscript 2.0

    上の本よりもさらにOOPプログラマ向け。同じOOP本ということでやや重複しており、こちらはMX2004時代の本なので見送ってもいいかも。分かりやすい英語で良著。この本のAS3版が出たら間違いなく買い。

Page Top