XML ファイルにアクセスし、そのコンテンツを取得し、その情報を使用して多数のテキスト フィールドに入力する必要があるアプリケーションを Actionscript 2 で作成しています。これは、フレームベースのアクション スクリプトでは簡単でした。なぜなら、私がしなければならなかったことは、何かをやめて、次のステップを XML.onLoad 関数から実行するように設定するだけだったからです。しかし、私はこのことをクラスファイルで書き直しています.XMLが既に存在することに依存している関数が呼び出される前に、XMLをロードするのに苦労しています.
詳しく説明すると、
クラス、メインがあるとしましょう。そのクラスは次のようになります。
import XMLItems;
class Main {
private var _xmlItems:XMLItems;
public function Main() {
_xmlItems = new XMLItems();
_itemData = _xmlItems.getItemData();
}
今のところ大丈夫そうですよね?新しい XMLItems インスタンスを作成し、そのインスタンスの getItemData() メソッドを呼び出すだけです。
XMLItems は次のとおりです。
import mx.xpath.XPathAPI;
import XMLLoader;
class XMLItems {
private var _loader:XMLLoader;
private var _itemData:XML;
private var _eventPath:String = "/*/dbresult/playlist/";
public function XMLItems() {
trace('XMLItems object instantiated.');
}
private function parseItemData(itemData:XML):Array {
var nodes:Array = XPathAPI.selectNodeList(itemData, _eventPath + "item");
return nodes;
}
public function getItemData():Array {
_loader = new XMLLoader();
_itemData = _loader.getXML();
var r:Array = parseItemData(_itemData);
return r;
}
}
これで、getXML 関数を呼び出せるように作成する XMLLoader オブジェクトができました (心配しないでください。最後の関数です)。
import mx.xpath.XPathAPI;
class XMLLoader {
private var _rawXML:XML;
private var _xmlLocation:String = '';
private var _recommendRequestURL:String;
private var _xmlIsLoaded:Boolean = false;
private var _eventPath:String = "/*/dbresult/playlist/";
public function XMLLoader() {
trace('Instantiating XML loader...');
_recommendRequestURL = _root.recmReqUrl ? _root.recmReqUrl : escape('http://www.myURL.com/');
_rawXML = new XML();
_rawXML.ignoreWhite = true;
var host = this;
_rawXML.onLoad = function(success:Boolean) {
if (success) {
_xmlIsLoaded = true;
trace('XML data was successfully loaded.');
var nodes:Array = XPathAPI.selectNodeList(host._rawXML, host._eventPath + "item");
trace("Number of XML nodes: " + nodes.length);
trace("Sample node: " + nodes[nodes.length - 1]);
} else {
trace('There was an error loading the XML. Please check the XML file.');
}
}
loadXML();
}
private function loadXML():Void {
var xmlLocation:String;
if ( !_root.recmReqUrl ) {
trace("There is no network address for the XML file. Defaulting to local settings.")
xmlLocation = './localBannerData.xml';
} else {
xmlLocation = _recommendRequestURL.concat( '&spec=', 'specInfo', 'getCatInfo()', 'getXCatInfo()', '&t=', new Date().getTime() );
}
if ( _rawXML.load( xmlLocation ) ) {
trace('Loading XML file: ' + xmlLocation);
} else {
trace('I\'m having difficulty finding the XML. You might want to check your data source.')
}
}
public function getXML():XML {
return _rawXML;
}
}
問題は、getXML 関数が呼び出されたときに、XML がまだロードされていないことです。したがって、私がこれを行ったにもかかわらず、メソッドは空の XML オブジェクトを XMLItems クラスに返しています。
_loader = new XMLLoader();
_itemData = _loader.getXML();
これは、次のステートメントが評価される前にコンストラクターの実行を終了する必要があることを意味していました。どうやらそうではありません。
onLoad 関数によって設定されるブール値を作成し、(メソッドが返される前に) getXML メソッドに while (true) ループを配置して、そのブール値をチェックし、true を返す場合は中断しようとしましたが、true を返すことはありませんでした。そのため、永遠にループしました。
ここで何が起こっているのか本当にわかりません。クラスに XML を同期的に要求させて、XML が来るまでただ冷やすことができないのはなぜですか?
ありがとう、SS