AS3 parse XML to multidimensional array?
I use this code to load XML im Flash:
Sample XML file:
<playlist>
<track>
<title>TestTrack 1</title>
<band>Band1</band>
<file>test1.mp3</file>
</track>
<track>
<title>TestTrack 2</title>
<band>Band2</band>
<file>test2.mp3</file>
</track>
<track>
<title>TestTrack 3</title>
<band>Band3</band>
<file>test3.mp3</file>
</track>
<track>
<title>TestTrack 4</title>
<band>Band4</band>
<file>test4.mp3</file>
</track>
</playlist>
AS3 source:
var xmlLoader:URLLoader = new URLLoader();
xmlLoader.addEventListener(Event.COMPLETE, showXML);
xmlLoader.load(new URLRequest("playlistAS3.xml"));
function showXML(e:Event):void {
XML.ignoreWhitespace = true;
var songs:XML = new XML(e.target.data);
trace(songs.track.length());
var i:Number;
开发者_C百科 for (i=0; i < songs.track.length(); i++) {
trace(" Name of the song: "+ songs.track[i].title.text());
trace(" Name of the Band: "+ songs.track[i].band.text());
trace(" File Location of the song: "+ songs.track[i].file.text());
}
}
Here everything is alright, but I would like to do more than just trace the results. I would like to store the results in an object or an array and access it from other functions.
My question is how to store XML data if I want to use it from other functions?
From what I'm understanding, you just want to parse the xml and put the contents into an object. Something like this:
var songs:XML;
var songsObj:Object = new Object();
function showXML(e:Event):void {
XML.ignoreWhitespace = true;
songs = new XML(e.target.data);
var len:int = songs.track.length();
for (var i:int = 0; i<len; i++) {
trace(" Name of the song: "+ songs.track[i].title.text());
trace(" Name of the Band: "+ songs.track[i].band.text());
trace(" File Location of the song: "+ songs.track[i].file.text());
songsObj[i] = {
song:songs.track[i].title.text(),
band:songs.track[i].band.text(),
file:songs.track[i].file.text()
};
}
customFunction();
}
function customFunction():void {
trace(songs.track[0].title.text()); // traces TestTrack 1
trace(songsObj[0].song); // also traces TestTrack 1
}
I'm not sure if this is what you're looking for or how you're wanting to access the data from other functions...but, you could also just use the "songs" XML variable rather than creating an object that essentially duplicates the data that exists in the XML.
The best way to store xml data is with classes in my opinion, look at the following example I made:
package
{
import flash.display.Sprite;
import flash.events.Event;
public class Main extends Sprite
{
public function Main():void
{
if (stage) init();
else addEventListener(Event.ADDED_TO_STAGE, init);
}// end function
private function init(e:Event = null):void
{
removeEventListener(Event.ADDED_TO_STAGE, init);
var playlistXml:XML = <playlist>
<track>
<title>TestTrack 1</title>
<band>Band1</band>
<file>test1.mp3</file>
</track>
<track>
<title>TestTrack 2</title>
<band>Band2</band>
<file>test2.mp3</file>
</track>
<track>
<title>TestTrack 3</title>
<band>Band3</band>
<file>test3.mp3</file>
</track>
<track>
<title>TestTrack 4</title>
<band>Band4</band>
<file>test4.mp3</file>
</track>
</playlist>;
var playlist:Playlist = new Playlist(playlistXml);
var track:Track = playlist.getTrackByTitle("TestTrack 1");
trace(track.band); // output: Band1
}// end function
}// end class
}// end package
internal class Playlist
{
private var _tracks:Vector.<Track>;
public function Playlist(playlistXml:XML)
{
_tracks = new Vector.<Track>();
for each(var track:XML in playlistXml.children())
{
_tracks.push(new Track(track.title, track.band, track.file));
}// end for each
}// end function
public function getTrackByTitle(title:String):Track
{
var track:Track;
for each(var t:Track in _tracks)
{
if (t.title == title) track = t;
}// end for each
if (!track) throw new Error("Could not find track with title " + "\"title\".");
return track;
}// end function
public function getTrackByBand(band:String):Track
{
var track:Track;
for each(var t:Track in _tracks)
{
if (t.band == band) track = t;
}// end for each
if (!track) throw new Error("Could not find track with band " + "\"band\".");
return track;
}// end function
public function getTrackByFile(file:String):Track
{
var track:Track;
for each(var t:Track in _tracks)
{
if (t.file == file) track = t;
}// end for each
if (!track) throw new Error("Could not find track with file " + "\"file\".");
return track;
}// end function
}// end class
internal class Track
{
private var _title:String;
private var _band:String;
private var _file:String;
public function get title():String { return _title }
public function get band():String { return _band }
public function get file():String { return _file }
public function Track(title:String, band:String, file:String)
{
_title = title;
_band = band;
_file = file;
}// end function
}// end class
In the document class Main
there's the playlistXml
object with the playlist xml data(didn't put the code to load it because I didn't want to make the code bigger than it already was, well is).
Next comes the Playlist
object. This is an object of a class that handles breaking up the track nodes in the xml and storing them in Track
objects. Also the Playlist
class has three public methods called, getChildByTitle()
, getChildByBand()
, getChildByFile()
, that searches for and a specified track by the respective method.
The advantage of this approach is that it creates a strong construct for storing your data and allows for an easy way to retrieve it.
var track:Track = playlist.getTrackByTitle("TestTrack 1");
trace(track.band); // output: Band1
精彩评论