トップへ戻るニュースフォーラムFLASH-ML 過去ログBak@Flaダウンロードよくある質問と答
ログイン
ユーザ名:

パスワード:


パスワード紛失

新規登録
メインメニュー
メイン
   コーダーズルーム【スクリプト系】
     自作クラスの中のXMLオブジェクト
投稿するにはまず登録を

スレッド表示 | 新しいものから 前のトピック | 次のトピック | 下へ
投稿者 スレッド
two_line
Åê¹ÆNo.13626
投稿日時: 2004-12-24 23:01
新米
居住地: Yokohama, Japan
投稿: 16
使用環境:
FLASH CS3, Windows XP
自作クラスの中のXMLオブジェクト
初めまして。よろしくお願いいたします。

<質問>
クラスにプロパティとして存在しているXMLオブジェクトの
loadメソッドは使えないのでしょうか。
FLASHヘルプのXMLのloadの項を参照しても解決しない私にどうか教えて下さい…。

↓のようなクラスを作りました。
------------------------------------------

class XMLObj{
	private var contents : String;
	private var xmlObj : XML;
	
	// コンストラクタ
	// ・ファイル名(引数)からXMLファイルの中身を読み出す
	// ・XMLオブジェクトに読み出したデータを設定する
	function XMLObj(fileName:String){
		// SHIFT-JISの読み込みを可能にする
		System.useCodepage = true;
		
		xmlObj = new XML();
		xmlObj.ignoreWhite = true;
		
		// XMLの読み込みが完了したらXMLデータを
		// 文字列オブジェクトcontentsに
		// 設定するメソッドを実行する
		xmlObj.onLoad =  xmlObjToString;
		xmlObj.load(fileName);
	}
	
	// 文字列オブジェクトcontentsにデータを設定する
	function xmlObjToString( success : Boolean):Void{
		if( success ){
			contents = xmlObj.toString();
			trace("loading success ::: " + xmlObj.toString());
		}else{
			trace("loading fail.");
		}
	}
	
	// 読み出したデータを返却する
	function getContents() : String{
		trace("contents >>>" + contents);
		return contents;
	}
}

---------------------------------------------

これをタイムラインから
var xmlObj : XMLObj = new XMLObj("test.xml");
trace("trace >>> " + xmlObj.getContents());
のように実行します。すると出力ウィンドウに↓のように、
"undefined"という値しか表示されないのです。

---------------------------------------------
contents >>>undefined
trace >>> undefined
loading success ::: undefined
---------------------------------------------

どうかご教授宜しくお願いいたします。
野中文雄
Åê¹ÆNo.13628
投稿日時: 2004-12-25 0:11
ちょんまげら
居住地: 東京
投稿: 4531
使用環境:
CS5.5 .6.8 Vista Home Premium (SP1)
Re: 自作クラスの中のXMLオブジェクト
ケアレスミスも含めて、何点かポイントがありますね。まずは、動作するスクリプトを確認していただいて、おわかりにならない点を改めてご質問いただく方がよさそうです。
引用:
two_lineさんは書きました:
クラスにプロパティとして存在しているXMLオブジェクトの
loadメソッドは使えないのでしょうか。
...[中略]...
これをタイムラインから
var xmlObj : XMLObj = new XMLObj("test.xml");
trace("trace >>> " + xmlObj.getContents());
のように実行します。すると出力ウィンドウに↓のように、
"undefined"という値しか表示されないのです。
contents >>>undefined
trace >>> undefined
loading success ::: undefined

// Flashムービー(SWF)
// フレームアクション
var xmlObj:XMLObj = new XMLObj("test.xml");
this.onMouseUp = function() {
	trace("trace >>> "+xmlObj.getContents());
};

// ActionScript 2.0クラス定義ファイル: XMLObj.as
class XMLObj {
    private var contents:String;
    private var xmlObj:XML;
    // コンストラクタ
    // ・ファイル名(引数)からXMLファイルの中身を読み出す
    // ・XMLオブジェクトに読み出したデータを設定する
    function XMLObj(fileName:String) {
        // SHIFT-JISの読み込みを可能にする
        System.useCodepage = true;
        xmlObj = new XML();
        xmlObj.ignoreWhite = true;
        // XMLの読み込みが完了したらXMLデータを
        // 文字列オブジェクトcontentsに
        // 設定するメソッドを実行する
        xmlObj["owner"] = this;
        xmlObj.onLoad = xmlObjToString;
        xmlObj.load(fileName);
    }
    // 文字列オブジェクトcontentsにデータを設定する
    function xmlObjToString(success:Boolean):Void {
        if (success) {
            // contents = xmlObj.toString();
            this["owner"].contents = this.toString();
            // trace("loading success ::: "+xmlObj.toString());
            trace("loading success ::: "+this.toString());
        } else {
            trace("loading fail.");
        }
    }
    // 読み出したデータを返却する
    function getContents():String {
        trace("contents >>>"+contents);
        return contents;
    }
}


----------------
 

野中文雄
Åê¹ÆNo.13629
投稿日時: 2004-12-25 0:25
ちょんまげら
居住地: 東京
投稿: 4531
使用環境:
CS5.5 .6.8 Vista Home Premium (SP1)
Re: 自作クラスの中のXMLオブジェクト
先の回答をご理解いただいたうえで、7.2ならDelegateクラスを使うのがスマートかもしれません。
// ActionScript 2.0クラス定義ファイル: XMLObj
import mx.utils.Delegate;
class XMLObj {
    private var contents:String;
    private var xmlObj:XML;
    // コンストラクタ
    // ・ファイル名(引数)からXMLファイルの中身を読み出す
    // ・XMLオブジェクトに読み出したデータを設定する
    function XMLObj(fileName:String) {
        // SHIFT-JISの読み込みを可能にする
        System.useCodepage = true;
        xmlObj = new XML();
        xmlObj.ignoreWhite = true;
        // XMLの読み込みが完了したらXMLデータを
        // 文字列オブジェクトcontentsに
        // 設定するメソッドを実行する
        xmlObj.onLoad = Delegate.create(this, xmlObjToString);
        xmlObj.load(fileName);
    }
    // 文字列オブジェクトcontentsにデータを設定する
    function xmlObjToString(success:Boolean):Void {
        if (success) {
            contents = xmlObj.toString();
            trace("loading success ::: "+xmlObj.toString());
        } else {
            trace("loading fail.");
        }
    }
    // 読み出したデータを返却する
    function getContents():String {
        trace("contents >>>"+contents);
        return contents;
    }
}


----------------
 

two_line
Åê¹ÆNo.13634
投稿日時: 2004-12-25 11:26
新米
居住地: Yokohama, Japan
投稿: 16
使用環境:
FLASH CS3, Windows XP
Re: 自作クラスの中のXMLオブジェクト
こんにちは。
野中様、ご回答真に有難う御座いました。
お蔭様で期待していた動作が確認できました。
さらに疑問点が生じましたので甘えて質問させて頂きます。

?xmlObj["owner"] = this;
?this["owner"].contents = this.toString();
という記述についてです。

☆1
?の記述は何故必要なのでしょうか。
XMLObjオブジェクト自身をXMLオブジェクトに参照させなければならない理由を教えて下さい。
あ、考えているうちに今、自分なりの答が出ました。
答は、"そのXMLオブジェクトを持つオブジェクトが誰なのかわからないと、XMLデータのload先が分からないから"
でしょうか。

☆2
?の記述についてです。これもまた、今自分なりの答が出ました。
「thisはXMLObjインスタンス自身なのに、this.toString()が機能するのは変だなぁ」と思ってましたが、
?のような記述が必要な理由は、xmlObjToString( )というメソッドは
XMLオブジェクトのものだからだとしたら、すっきりしました。
Javaと差があって、ちょっと難ありですね…。
onLoadイベントで呼び出しているメソッドは、
イベント駆動で呼び出したオブジェクトのメソッドなんでしょうか。

☆1・☆2について、どうでしょうか。これらは常識なんですかね?
野中文雄
Åê¹ÆNo.13635
投稿日時: 2004-12-25 12:40
ちょんまげら
居住地: 東京
投稿: 4531
使用環境:
CS5.5 .6.8 Vista Home Premium (SP1)
Re: 自作クラスの中のXMLオブジェクト
まずは、動作して何よりです。

以下のご質問にお答えするには、XMLインスタンスxmlObjにコールバック関数として設定するメソッドxmlObjToString()の中の、以下のステートメントにご注目いだくとよいでしょう。
// contents = xmlObj.toString();
this["owner"].contents = this.toString();
引用:
two_lineさんは書きました:
(1)xmlObj["owner"] = this;
(2)this["owner"].contents = this.toString();
という記述についてです。

まず、ActionScript 2.0クラス定義内では、参照先を省略した場合、this参照が自動的に補われます[*1]。ここで注意しなければならないのは、コールバック関数のように、オブジェクトインスタンスに対して設定された関数ブロック({})内のthis参照です。

上記ステートメントからわかることは、コールバック関数内のthisは、その「設定先」であるxmlObjを参照するということです。つまり、thisはクラスXMLObjのインスタンスを参照しません。

ところが、コールバック関数内でもうひとつ参照したいcontentsは、XMLObjクラスのプロパティです。xmlObjもXMLObjクラスのプロパティですから、感覚的にいえば自分の親(タイムラインなら_parent)の参照を得る必要があります。しかし、タイムラインと異なり、プロパティからその持ち主(親)を参照する手段がありません。

そこで、xmlObjプロパティの持ち主であるXMLObjクラスのインスタンス(this)を、xmlObjのプロパティとして設定することが考えられます。これが、xmlObj.ownerです。(1)のステートメントは、この設定を行っています。
引用:
(1)の記述は何故必要なのでしょうか。
XMLObjオブジェクト自身をXMLオブジェクトに参照させなければならない理由を教えて下さい。

コールバック関数内のthisは、関数の設定先であるxmlObjプロパティを参照しますので、this.toString()はxmlObj.toString()と同じ意味になります。ただし、コールバック関数内でxmlObj.toString()と記述すると、thisが補われて、this.xmlObj.toString()と解釈されます。thisはxmlObjプロパティを指す訳ですから、その中にさらにxmlObjというプロパティを探しても存在しません(undefinedと認識されます)。
引用:
(2)の記述についてです。これもまた、今自分なりの答が出ました。
「thisはXMLObjインスタンス自身なのに、this.toString()が機能するのは変だなぁ」と思ってましたが、

実は、上記ステートメントには、もうひとつポイントがあります。xmlObj.ownerとせずに、xmlObj["owner"]と記述した点です。

xmlObjプロパティは、ActionScript 2.0シンタックスにより、XMLクラスで型づけされています。そのため、xmlObj.ownerと記述すると、XMLクラスにそのようなプロパティが存在しないので、コンパイルエラーになってしまいます。

厳密な「作法」に従うなら、xmlObjのクラスをXMLのサブクラスとして定義することになるところです。しかし、今回は少し面倒なので、裏技を使用しています。配列アクセス演算子([])を使ってプロパティにアクセスすれば、型チェックが回避できるのです。

ただし、この裏技で設定したプロパティにアクセスするには、つねに配列アクセス演算子を使用する必要があります((2)のステートメントは、そのため配列アクセス演算子を使用しています)。また、この手法の多用は、型指定を無意味にするので、もちろんお勧めしません。

なお、Delegateクラスを用いれば、コールバック関数のthis参照先を変更できるので、この裏技を使用する必要もなく「スマート」かなと考えた次第です。

最後に、機種依存文字は使用を避けましょう。
_____
[*1] この点は、タイムラインに記述したスクリプトとは異なります


----------------
 

two_line
Åê¹ÆNo.13709
投稿日時: 2004-12-29 11:21
新米
居住地: Yokohama, Japan
投稿: 16
使用環境:
FLASH CS3, Windows XP
Re: 自作クラスの中のXMLオブジェクト
こんにちは。

返答が遅くなって申し訳ありません。
様々なポイントをわかりやすく
ご教授いただき、真に有難うございました。

ActionScriptヘルプを隅々まで読んで
もっと努力しようと思います。

※機種依存文字使ってすいません。
スレッド表示 | 新しいものから 前のトピック | 次のトピック | トップ

投稿するにはまず登録を
 
Copyright (C) 2003 FLASH-japan. All rights reserved.
Powered by Xoops