
(Click image to open XML-based Flash movie in sized window)
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).
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.
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.
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):
To read an XML file into an XML instance in Flash, you need to do 5 things:
// 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.
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.
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:
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.
last update: 22 Sep 2006
Discussed on this page:
what is xml, how to use xml with flash, xml structure, read xml and convert to array of objects, use xml data as dataprovider for v2 components
Files:
peopledisplay.fla
people.xml
(free download)
fla, as, xml, swf's for example at left
In xmlexample.zip, password required
Subscription:
A password may be obtained by subscription
An access password will be emailed to the address you specify within 24 hours of receipt of payment, and will remain active for 30 days thereafter. A list of all files currently available at the site may be viewed here.
Other Resources
Luke Tupper's Flash-XML FAQ is the place to look for answers to questions about Flash and XML.