SAVING Flash (AS3) data to XML
I've been all over the interwebs, including Stack Overflow, for hours, trying to identify a solid, workable example of saving information in Flash into an XML file.
I want to take the positions of two different types of objects and export the lists of each to XML. We'll call the objects ball and bat.
So, I'd love to have the XML look something like:
<objects>
<ball xPos=34 yPos=43/>
<ball xPos=12 yPos=94/>
<bat xPos=1 yPos=39/>
</objects>
Sounds simple enough, but I haven't been able to find a single decent example for exactly what AS3 code can accomplish this. The data is in two vectors of MovieClips, so I'd be using bats[i].x and bats[i].y for 开发者_开发知识库input values.
How can I create this XML, and save it somewhere local to view? Thank you for any help at all, this has proved extremely frustrating.
Working with XML in AS3 is really easy, so to expand on TheDarkIn1978's answer with some code:
Creating an XML object:
var objs:XML = new XML( <objects /> ); // create the <objects /> node
// for your objects
var ball1:XML = new XML ( <ball /> ); // create the <ball /> node
ball1.@xPos = 12; // add 12 as an attribute named "xPos"
ball1.@yPos = 42; // add 42 as an attribute named "yPos"
objs.appendChild( ball1 ); // add the <ball> node to <objects>
// an example of using variables in your xml
var name:String = "something";
var sx:XML = new XML( <{name} /> ); // creates a node <something />
Use the TheDarkIn1978's to the XML
class in AS3 to learn more.
Saving out your file:
// saving out a file
var f:FileReference = new FileReference;
f.save( sx, "myXML.xml" ); // saves under the name myXML.xml, "sx" being your root XML node
Compressing your XML before saving (with large XML files, this can save a lot):
// compressing before saving
var f:FileReference = new FileReference;
var bytes:ByteArray = new ByteArray;
bytes.writeUTFBytes( myXML ); // "myXML" being your root XML node
bytes.compress(); // compress it
f.save( bytes, "myXML.xml" );
Loading in a compressed XML, uncompressing it, and retrieving the XML object:
// uncompressing a compressed xml
var loader = new URLLoader;
loader.dataFormat = URLLoaderDataFormat.BINARY;
// listen for our events
loader.addEventListener( Event.COMPLETE, this._onLoad );
loader.addEventListener( IOErrorEvent.IO_ERROR, this._onFail ); // not shown
loader.addEventListener( SecurityErrorEvent.SECURITY_ERROR, this._onSecurityError ); // not shown
private function _onLoad( e:Event ):void
{
var loader:URLLoader = e.target as URLLoader;
// get the data as a bytearray
var ba:ByteArray = loader.data as ByteArray;
// uncompress it
try
{
ba.uncompress();
}
catch ( e:Error )
{
trace( "The ByteArray wasn't compressed!" );
}
// get our xml data
myXML = XML( ba );
}
I created a simple tool for compressing/uncompressing XML files. You can get the SWF and source at http://divillysausages.com/blog/xml_compressor_uncompressor if you're interested
ActionScript 3.0 is built with E4X, so you can create XML objects at runtime and then write them to disk as text files (with .xml extension, of course).
if you're programming for browser-resident Flash, you can use flash.net.FileReference, but this approach presents a dialog window to load/save files. if you're programming in AIR you can load/save files as background processes using flash.fileSystem.File.
i'm assuming you are programming for the browser and would like to handle the data in the background. in this case, you also have the (very common) option of using a Local Shared Object to store and retrieve your XML data object.
more here (including sample code): flash.net.SharedObject
I think it might be easier in some instances to just create a string in as3 and then cast it as xml at the end:
import flash.geom.Point;
var cordiantes = [new Point(34,12),new Point(14,2), new Point(10,15)];
var objects = ["ball","ball","bat"];
// starting the object node.
var myXmlStr = "<objects>";
for(var i = 0; i < objects.length; i++)
{
// adding things to the string between the object nodes.
myXmlStr += "<" + objects[i] + " xPos= '" + cordiantes[i].x + "' yPos='" + cordiantes[i].y + "' />";
}
// closing the objects node.
myXmlStr += "</objects>";
// turning the string into xml.
var xmlfinal:XML = XML(myXmlStr);
trace(xmlfinal);
Output is:
<objects>
<ball xPos="34" yPos="12"/>
<ball xPos="14" yPos="2"/>
<bat xPos="10" yPos="15"/>
</objects>
This would make it easy to make changes and add attributes to the objects later.
also if you're using an array of movieclips it gets even easier.
Just an addition to divillysausages' answer (that I upvoted).
If you want to add a value to the xml tag, like:
<ball>red ball</ball>
You can use:
var ball:XML = <ball />.appendChild("red ball");
Obviously you can pass to appendChild a String variable.
精彩评论