AS Reference  :  Notes Index  :  Resources  :  About/Contact  :  Downloads

Using an XML file with Flash



(Click image to open XML-based Flash movie in sized window)

What is XML and how is it used with Flash?

XML (EXtensible Markup Language) is a way of structuring information in a text-based file using tags that are similar to HTML tags, but not predefined as HTML tags are. Instead, you make up the tags (or use one of the evolving XML application standards) which best define your data structure, or use the XML file generated by conversion from spreadsheet or database content. Providing your XML file follows the correct structure (one root tag enclosing all others, tags nested within others, and all tags properly closed), Flash can read the file and convert it to an instance of the XML class. As of Flash MX 2004, Flash does not use DTDs (Document Type Definition files), which are used by some other XML-reading applications. Instead, Flash allows you to read information in an XML file into an instance of the XML class, which has predefined methods and properties associated with it.

Like the other types of operations involving accessing files on a web server, XML access is an asynchronous operation. You issue a command to load the XML, but you cannot follow that command with a statement which requires that the XML contents be available, as they won't be immediately available. Instead, before you issue the load command, you set up a function and assign it to the XML instance's onLoad event property; that function contains everything you want to have happen once the XML data is available (including parsing the XML into a useable format if necessary, calls to other functions, etc).

Why use an XML file?

XML files provide a useful way to save your information in a logical, human-readable and easily edited (with any text editor) format and pass it to a Flash movie. That information can include external jpg or swf names (to be loaded dynamically while the movie is running), directory paths to information the movie will need, x and y pixel locations to place objects on stage, color information, text information like addresses -- anything which you might want to provide to a Flash movie dynamically, so that new content can be provided to the movie without having to edit and republish the fla. XML is also a universal standard format, so the same XML file can be used with Flash and any other application that reads XML.

Working with XML files

Like actionscript, XML has its own strict syntax rules which must be followed if the file is to be read at all by Flash. Incorrectly formatted files will often simply fail to be read. To check the structure of your XML file and/or edit it, you can use XMLSpy (a commercial product), or something like Microsoft's XML Notepad (no longer available from Microsoft). A word of warning that trying to edit your xml file in Dreamweaver MX can prove calamitous, as I found out when working on the sample above and found huge portions of it occasionally irretrievably disappearing after saving. I finally switched to Notepad and had no adverse effects when saving the file there.

In the sample above, I wanted to pass several things dynamically to the Flash movie: the date of last update and directory to find the swf's in, and, for each person listed, the person's name, the name of their related background swf, the color behind the swf, the text description of the person, and a blurb with links. I separated the links from the general description so I could show an example of passing html text versus ordinary text.

The parts of an XML Instance

When an XML file is read into Flash, it is converted to an instance of the XML class. An XML instance consists of one main node (of type XMLNode, and addressable as xmlinstance.firstChild) and an Array of one or more childNodes (each of type XMLNode) within it (addressable individually as xmlinstance.firstChild.childNodes[0], xmlinstance.firstChild.childNodes[1], etc). Each childNode may have an array of childNodes within it, and that structure of childNodes within childNodes may continue ad infinitum.

Every node in the XML file is either of type 1, a tag-based node, or type 3, a text node. This information is contained in the nodeType property of the node. (Other methods and properties of the XMLNode class may be found in the Help docs, under Actionscript 2.0 Language Reference, Actionscript Classes, XMLNode).

A tag-based node consists of an opening tag, (optional) attributes, and either a closing tag, or "/>" at the end of the tag, if no text nodes are contained within it. Attributes are listed in the opening tag, in the form attributename="attributevalue", separated by spaces. They are accessible via the attributes property (an instance of type Object) of the node they are part of. Nodes which contain text nodes must be closed by having a closing tag follow the text node.

A text node consists only of text entered inside a tag-based node, or text surrounded by "!<CDATA[" and "]]" if tags within the node are to be ignored.

Here is an explanation of the xml file used in the example above (people.xml, which you can download with the free download link at right):

Using XML in Flash

To read an XML file into an XML instance in Flash, you need to do 5 things:

  1. create a new XML instance,
  2. set its properties (optional),
  3. set up a function to do what you want with the instance once your XML file has been read,
  4. assign that function to the onLoad property of the XML instance,
  5. start the XML load
You should also import the Delegate class if you want your onload function to retain the scope of wherever it is typed (the main timeline, eg) instead of being the XML instance (as first introduced on this page). This is the skeletal code, as copied from the example above:

Framework for reading an XML file
// import the Delegate class
import mx.utils.Delegate;

// declare a new XML instance
var peoplexml:XML = new XML();

function onXmlLoaded(success:Boolean) {
   if (success) {
      // do whatever you want to do if the XML file was read successfully
      // use peoplexml.firstChild to access the main node
   } else {
      // do whatever you want to do if an XML read error occurred
   }
}

function init() {
   // ignore tabs, returns, and other whitespace between nodes
   peoplexml.ignoreWhite = true;	

   // set the scope of the onLoad function to the main timeline, not peoplexml
   peoplexml.onLoad = Delegate.create(this, onXmlLoaded);
	
   // start loading the file
   peoplexml.load("people.xml");	   
}

init();

Try pasting the code above into a new blank movie, replacing "// do whatever you want to do if an XML read error occurred" with "trace('error reading file');" (without quotes) and you should see your error message, plus a Flash built-in error message, appear in the Output panel when the movie is tested.

Getting XML content into a Recordset structure

In most cases where I have a need for information from an XML file, I find that the most useful structure to have that information in is a recordset (Array of Objects), not an XML instance. An XML instance consists of arrays of nodes of text strings within other arrays of nodes of text strings, which is not conducive to efficiently sorting, displaying or otherwise using the information at hand. An array of objects, on the other hand, can be easily sorted (using the sortOn method of the Array class), spliced, used as a dataProvider for the v2 components, etc. So, here is the code I used to convert my xml file to such a structure (array people, assumed to be created previously in the variable declaration section of the code):

// define what should happen when the XML loads
// (read data into update, dirpath, and people variables)
function onXmlLoaded(success:Boolean) {
   if (success) {
      // make a handle to the root node in the xml
      var mainnode:XMLNode = peoplexml.firstChild;
      update = mainnode.attributes.lastupdate;
      dirpath = mainnode.attributes.dir;
	
      // set up an array of all person nodes
      var peoplenodes:Array = peoplexml.firstChild.childNodes;
      for (var i:Number = 0; i < peoplenodes.length; i++) {
         // for each person node:
         var personnode:XMLNode = peoplenodes[i];
         people.push(
            {i:i+1,
             pname:personnode.attributes.name,
             bgcolor:parseInt(personnode.attributes.bgcolor, 16),
             photo:personnode.attributes.photo,
             bgswf:personnode.childNodes[0].attributes.url,
             desc:personnode.childNodes[1].firstChild.nodeValue,
             links:personnode.childNodes[2].firstChild.nodeValue
         });
      }
	  // data is all read and put in the right place -- now setup the screen
	  // using this data
      setup();
   } else {
      trace('error reading XML');
   }
}

The line beginning "people.push(" is where the array (people) of objects is constructed, with one element added for each childNode (person) of the people node in the XML file. Notice that the bgcolor attribute which comes in as a string (as all attributes do) must be converted to a hex number (for use with the Color class's setRGB method), which is done with the parseInt function.

Using the recordset contents in the Flash movie

That's it for reading and converting the XML contents to an array structure. Once you have done that, you can then use that array to populate one of the v2 components, like the ComboBox (dropdown) and display the information in the movie. Here's an example where we use the contents of the array to populate a ComboBox, which when selected displays the related text in a TextArea component and changes the background color of the movie to the color specified in the XML file:


Download fla and xml here

To recreate this example, start a new movie and

// import this so it can be used to set the scope of the combobox listener and the xml onload routine
import mx.utils.Delegate;

// declare variables
var people:Array;
var update:String;
var dirpath:String;

// create a new color object to associate with the bgcolor movieclip
var bgcol:Color;

// set up the XML instance
var peoplexml:XML = new XML();

// initialize items on stage
_global.style.setStyle("fontFamily", "Verdana");
_global.style.setStyle("fontSize", 11);

// define what should happen when the XML loads
// (read data into update, dirpath, and people variables)
function onXmlLoaded(success:Boolean) {
   if (success) {
      // make a handle to the root node in the xml
      var mainnode:XMLNode = peoplexml.firstChild;
      update = mainnode.attributes.lastupdate;
      dirpath = mainnode.attributes.dir;
	
      // set up an array of all person nodes
      var peoplenodes:Array = peoplexml.firstChild.childNodes;
      for (var i:Number = 0; i < peoplenodes.length; i++) {
         // for each person node:
         var personnode:XMLNode = peoplenodes[i];
         people.push(
            {i:i+1,
             pname:personnode.attributes.name,
             bgcolor:parseInt(personnode.attributes.bgcolor, 16),
             photo:personnode.attributes.photo,
             bgswf:personnode.childNodes[0].attributes.url,
             desc:personnode.childNodes[1].firstChild.nodeValue,
             links:personnode.childNodes[2].firstChild.nodeValue
         });
      }
     // data is all read and put in the right place -- now set up the screen
     // using this data
      setup();
   } else {
      trace('error reading XML');
   }
}

function setup() {
   // set up chooseperson dropdown
   chooseperson.labelField = "pname";
   chooseperson.dataProvider = people;
   chooseperson.addEventListener("change", Delegate.create(this, loadScreen));
}

function loadScreen(evt:Object) {
   var thisitem:Object = evt.target.selectedItem;
   ta.text = thisitem.desc;
   ta.vPosition = 0;
   bgcol.setRGB(thisitem.bgcolor);
}

function init() {
   // initialize the people array
   people = [{pname:"Choose one"}];	
	
   // set up the xml instance to ignore whitespace between tags
   peoplexml.ignoreWhite = true;
	
   // set the scope of the onLoad function to the main timeline, not peoplexml
   peoplexml.onLoad = Delegate.create(this, onXmlLoaded);
	
   // initialize the bgcol color variable by associating it with the background movieclip
   bgcol = new Color(bgcolor);
	
   // start the xml loading
   peoplexml.load("people.xml");
}

init();

You can get the fla and xml file for this example here.

The sample shown at the top of the page uses the same code and embellishes it a bit more so that when the dropdown (combobox) is selected, the selected swf is moved to a depth above the other swfs and faded in, with the appropriate text displayed in a textarea component and the background color and links/info links changed appropriately. The complete code and related files for that example may be extracted (into the correct directory structure) from xmlexample.zip in the class directory.

Intro
Flash: What & How
Example Sites
Create
Draw, Edit Shapes
Gradients
More Drawing Tips
Import
A Sample
Animate
Frames, Keyframes
Motion Tweens
More Motion Tweens
Shape Tweens
Masks
Control
Stop/Replay
Movieclips Intro
Movieclip Reference
Site Structure 1
Slideshow Movieclip
Contact Form
Scroll Resume
Preloader
Site Structure 2
Publish
Display Options
Player Detection
Optimize
AS 2.0 Basics
Intro to Syntax
Playhead Commands
Playhead Cmds 2
Coded Tween
onEnterFrame
Intro to Classes
Declare/Assign
Comments, Trace
Simple Data Types
Arrays & Objects
Code Blocks
Operators
Beyond Buttons
Code Structure
Toggle Controls
Group of Buttons
Drag and Hit
Distort Magnifier
Scroll Text
Bee Game
Dart Shooter
Sound Control
Easing Slider
Easing Slider 2
Components Intro
Timers & Delays
Dynamic Content
Intro
Drawing API
Create Text
Attach Movieclips
Easing Slider 3
Easing Slider 4
Load jpg/swf
Sliding Viewer
Preload swf
XML
Easing Slider 5
Server Comm
LoadVars (w/ PHP)
AS - PHP Lookup
Text File
Database 1:LoadVars
Database 2:Remoting
Read from directory
AS 2.0 Classes
Intro
Math
Key
Date
Color
EventDispatcher
New Samples
Pie Chart
Event-model Emailer
Tween Sequence
Fuse Sequence
SVG in Flash
Bitmap Topo
SWF as Data Holder
Two-level Menu
Yahoo! Flash Maps
Class-based Game
ASTB Samples
Disclaimer
3D Outlines
Bounce Collide
Address Book
Save Drawings
Home  :  Notes Index  :  Resources  :  About/Contact  :  Downloads