Flash Components      Flash Menu      Flash Gallery      Flash Slideshow      FLV Player      Flash Form      MP3 Player      PhotoFlow      Flash CMS      3D Wall      Flash Scroller

Flash / AS



ASP.net / PHP






  Design & Effects
  Audio & Video
  User Interface





Introduction to XML in Flash
       by senocular

Example: Squirrel Finder
This example will cover how to generate a list of buttons based on loaded XML. Each button then, when clicked, displays information obtained from the XML associated with that button.

First, the XML document:


It should look a little something like the following (the entire file is not shown here):

<?xml version="1.0"?>
<menuitems sourceurl="http://spot.colorado.edu/~halloran/sqrl.html">
<item type="squirrel">
<species>Abert Squirrels</species>
<![CDATA[Abert squirrels (Sciurus aberti) are only found
in mountain regions of North America. In the United States
their range extends from extreme south-central Wyoming to New
Mexico and Arizona. There are six valid subspecies including
S.a. ferreus, True, the subspecies that is found along the
Rocky Mountains in Colorado. Abert squirrels are limited to
Ponderosa pine (Pinus ponderosa) forests in which they feed
and build their nests.]]>

Here laid out in this file is a list of items that will populate a simple menu in Flash. Each item has two strings associated with it, a species (of squirrel) and a description of the location of where that particular species can be found in the North America. Ultimately, when brought into Flash, a menu will appear with buttons for each item listed showing on that button the species of squirrel. When clicked, it will bring up a dialog which will display the location text associated with that species. The final result gives you this:

[ squirrel finder in action ]

Download ZIP


XML Structure
Once you decide what you want/need in terms of your project (in this case, make a squirrel finder), one of the first things to consider is the structure of the XML which is going to deliver your information. I've already decided that, so that kind of takes away much of the thinking that would normally take place here. Still, lets take a look at the XML document and how its set up.

What we're dealing primarily with is a list of an unspecified number of containing two specific pieces of information, species and location description that ends up becoming a menu. In addition to this information, such listed items also have an identifier to specify what kind of item we're dealing with (there can be many species of many kinds of things, though here, we only want squirrels). Since the overall objective is menu the root document element reflects that: <menu>. The list of items is itself its own entity so it deserves its own element to reside in, aptly named "menuitems." Menuitems has an added attribute called sourceurl specifying the location this information was obtained. It's not used at all by Flash, but it's good to have nonetheless. Within the menuitems element are the item elements that contain our desired information along with an attribute to specify type of item. Type here is a simple, known keyword used to describe the element. Attributes should not be used for housing excessive text or values of uncertain content. Each item element appropriately represents a single item in the list to appear in Flash. The two bits of information needed about this item are also contained within their own elements within the item element. These are <species> and <location>. Since the species name should be straight-forward and lacking complication, a simple text node should suffice. The location element, however, with the text it contains, may have some unforeseen characters that might conflict with a proper XML document. As such, it is put in a CDATA section.

<menu> - root of XML
<menuitems sourceurl=""> - container of items
<item type=""> - single item w/ type
<species></species> - container for species text
<location> - container for location text
<![CDATA[ ]]> - keep questionable text away from parser
- more items...

Preparing the Flash File
Now that we have or XML defined and more or less out of the way for the time being, its time to begin designing the interface to display this information. Eventually we will need to interpret that XML meaningfully when brought into Flash, but we'll get to that later. First the physical elements of the movie need to be constructed.

The squirrel finder's interface is pretty simple. We have two basic screen elements: an item button and an information dialog that appears when you click on an item button. That's about it. Items are symbols (MovieClips) that would need to be dynamically attached for each item in the XML while the information dialog only needs to be concerned with one instance of itself which appears only when requested by a clicked menu item.

The buttons for menu items will have to be fairly dynamic. The button itself is hand-drawn, but the label text will be included by the XML when its loaded. This will simply be a dynamic text field. on top of the button. The behavior of this button will also be dynamic, assigned when the XML is loaded at which point the button actually has a purpose. That really requires nothing when making the button other than making sure you give it an instance name. Once the button is complete, it goes in an item movie clip that will reside in the Library awaiting to be attached (since its being attached, remember to make sure it has a linkage ID set).

[ item button ]

The information dialog is just a movie clip with a text field. that has a scrollbar thrown on to it. A close button is included to close this movie clip (hide it by setting _visible to false) when the viewer is done looking at the information. This movie clip and another empty movie clip will be the only elements on the stage when the Flash movie starts. The empty movie clip is used to attach menu items in (our buttons) which will be performed when the XML file has been loaded and interpreted (in the file, the "empty" clip actually contains a light grey square though not as a necessity).

[ dialog on main timeline ]

Scripting the Squirrel
With the visual elements complete, you can start scripting and testing. Often it is a good idea, depending on how sure you are of your coding abilities, to build such interaction in Flash little by little in ways that allow you to test an uncompleted version for functionality before continuing. This is a debug as you go approach. It can be time consuming but can also save you frustration in the long run.

There are three basic parts to coding the squirrel finder. They are: defining basic navigation interaction - core behaviors of item buttons and the close button in the information dialog, successfully loading the XML document, and finally interpreting that document to build and assign functionality to the menu that results from it. We'll start with the navigation.

This is pretty simple. The navigation is simple. It would be just wrong to make a simple navigation difficult (and based on that, I haven't). There are two "screens," one containing the menu, "menu_mc", and the other an information dialog, "infobox_mc" (though the information dialog appears to be a floating window above what would be the menu, the menu is hidden for simplification). When one screen is shown, the other is hidden and vise versa. Item buttons hide the menu and show the information dialog while the close button performs respectively for doing the opposite. Each of these actions are defined in functions. Since the close button will actually be present when the function is defined, it can be set immediately to be the close button's onRelease event handler. Item buttons, however, won't exist until after the XML defining the menu has fully loaded and the menu has been created. So in the mean time, it will sit simply under a generic name, "DisplayInfo", until it can be set to individual items' onRelease events dynamically. Each button also contains code to alter the information dialog's contents.

function DisplayInfo(){
menu_mc._visible = false;
infobox_mc._visible = true;
infobox_mc.content_txt.text = this.location_text;
infobox_mc.close_btn.onRelease = function(){
menu_mc._visible = true;
infobox_mc._visible = false;
infobox_mc.content_txt.text = "";

You can see that each action pulls the old switcheroo in setting visibility between menu_mc and infobox_mc. DisplayInfo also sets the text field. text within infobox_mc to be a variable called "location_text" assigned to the owner of the function. Right now, that's nothing, but when this function gets assigned to an item button, that variable will reference that button's location_text property, a property assigned to that button based on content grabbed from the XML file. Conversely, the close_btn sets the text to "" or no text clearing the dialog.

Since both of these movieclips exist on the main timeline to start and only one can be visible at a time, that also means we need to set one to start invisible. That would be infobox_mc. That little line can go right below the functions defined above.

infobox_mc._visible = false;

Next lets tackle the menu creation. This is by far the hardest part of the entire file. It consists of a single function called CreateMenu. Passed into that function is one argument, the XML defining the menu which is to be created - and that is where the fun begins, using that XML data to build the menu of squirrels (items). Luckily this is a simple example so it will be easy to follow.

First we must make sure we understand what is being sent - what is in the XML. We covered the XML earlier, but in brief we have the following to deal with:

  • A list of menu items within the root node under the element "menuitems"
  • Each item element has a type attribute specifying what it is (each item of type "squirrel" will be represented as a menu item)
  • Items have two child elements, "species" and "location" each with text nodes (one using CDATA) to store their related content.

Technically, this list of menu items would be of an undetermined length. We don't really know how many squirrels will be in this menu or if/when new ones will be added. The beauty of using XML is that they can be added (or taken away) very easily without ever touching Flash. All anyone has to do is edit the XML with a text editor and you're set - that is if we're smart enough to make Flash do that. How is with a loop.

Looping is what will get us through the list of menu items. Remember, elements are kept in childNodes arrays that exist in their parent nodes. Each item in the XML exists as an element in the menuitem element's childNodes array. A loop going through those array elements will give you each item no matter how many there are, and this we can tell using childNodes.length.

The loop gets you through each item. From there its just a matter of extracting the needed content and attaching a item movie clip to facilitate it. To help manage the attaching, two variables are used, one, a constant, to decide how far apart to space items as they are added and another to count the number of items attached (also provides a way to assign a unique depth to each one). These are called "item_spacing" and "item_count" respectively.

var item_spacing = 28;
var item_count = 0;

With that, lets look at what this function looks like:

function CreateMenu(menu_xml){
var items = menu_xml.firstChild.firstChild.childNodes;
for (var i=0; i<items.length; i++) {
if (items[i].attributes.type == "squirrel") {
var species = items[i].firstChild;
var location = items[i].childNodes[1];
var item_mc = menu_mc.attachMovie("menu_item","item"+item_count, item_count);
item_mc._y = item_count * item_spacing;
item_mc.species_txt.text = species.firstChild.nodeValue;
item_mc.main_btn.location_text = location.firstChild.nodeValue;
item_mc.main_btn.onRelease = DisplayInfo;

You can see a fair number of variables being set here. The first few lines in the function you can see a couple of variable definitions. These aren't necessarily required definitions either. They simply provide shortcuts to paths in the xml. This not only keeps you from typing more, but it also makes the code a lot easier to understand. Its suggested that you do this as frequently as you can in XML code to help improve clarity.

The first variable, items, is the child nodes array of the menuitems element. The menuitems element is identified with:

var items = menu_xml.firstChild.firstChild.childNodes;

where menu_xml represents the XML object passed into the function. So this is saying get the child nodes of the first child of the first child of xml making up the menu_xml object. The XML object's first child is the root element menu. Menu's first child is menuitems and its childnodes represents the array of item elements we're after.

[ referencing items array through child nodes ]

We can now work with items more easily as it is a simple representation of the item elements array. There's no point in retyping all those firstChilds again if we don't have to. The items variable will also greatly improve code comprehension.

With the items variable assigned to the array of items, we can no begin cycling through that array creating menu buttons for each item and extracting/assigning content text where needed. This is where the for loop comes in.

for (var i=0; i<items.length; i++) {

As loops go, this is pretty self-explanatory. This creates a variable i which starts at 0 and increments by 1 while its value remains below the length of the items array. This lets us go through each item as item[i] and have the code within this loop execute for each.

Now we start getting into the accessing the information of the XML object (through the items array). There are three pieces of information we want to extract. First is the type of item to see if it should be included in our menu. Second is the species of our item (of our squirrel item) and finally the text specifying location.

The type of item is probably the easiest to extract. This information is held in an attribute of an item element and is accessible through the attributes object of that node in Flash. Within the for loop, items[i] represents the current (item) node in the loop iteration. The type would come from item[i].attribures.type. You can see that with the following if statement in the for loop:

if (items[i].attributes.type == "squirrel") {

This checks each item's type. If it matches "squirrel" then the code within the block (that which creates the menu items) is run, otherwise, the item is ignored. This means only squirrel items will make it into our menu - just in case some other type of item happened to find its way into the XML file.

Assuming the item is of type squirrel, two more variables are created. These are species and location from where we will extract the text specifying each.

var species = items[i].firstChild;
var location = items[i].childNodes[1];

The species element is the first child of the item element whereas location is the second child. Now, since there is no "secondChild" property like there is a "firstChild," we're just going to have to use childNodes and an index number to get the second child. Similarly, firstChild could be written as items[i].childNodes[0];. Remember, the text within, text nodes and CDATA, are not a part of the these elements. They exist as their own nodes - as children of those elements - whose text are obtained using the nodeValue property.

[ referencing child nodes in first item ]

With the species and location variables, it makes it a little more clear where we are and what references what. This will prevent the long stringing of firstChilds and childNodes references as seen in the chart above - or at least reduce them a little. You also get a clearer representation of what non-specific references like items[i].firstChild is - it's species.

Now, before actually using those variables, the menu button will need to be attached. The content we're ultimately extracting with those variables, the text and CDATA nodes, are going to be assigned with that button so it will need to be attached in order for that to happen. That's where the next clump of code comes into play.

var item_mc = menu_mc.attachMovie("menu_item","item"+item_count, item_count);
item_mc._y = item_count * item_spacing;

If you'll remember, two generic variables were defined earlier in the movie. These were item_count and item_spacing. In attaching a menu item is where these guys come into play. The item_count variable is used to count items as they are added to the menu. You can see that attachMovie is used to attach a "menu_item" symbol from the library into the menu_mc which exists on the main timeline. Item_count is used in attachMovie to not only give the new menu item a unique name, but also provide a unique depth for it to live within the menu_mc.

The attached clip, item_mc, is then positioned based on item_count and its value multiplied by item_spacing. For this example, the item_spacing was set at 28, or about the height of a menu button. When this is combined with an ever-increasing item_count variable, you get vertical positions starting at 0 and counting up by 28 each time item_count increases (item_count starts at 0 so 0 * item_spacing is 0 the first time around). You can see that the attached clip has its _y property set to this combination. Directly below it, item_count is increased so that the next attached button will be properly created and positioned accordingly.

At this point we can now snag the text out from the current item in the loop. This will be both the species text (text node) and the location text (CDATA section). The species text will be assigned as the text in the text field. located within the freshly attached item_mc named species_txt. The location text from the CDATA section will go into an arbitrary variable assigned within the item button (main_btn). This text is what each item button will send to the location dialog when it is clicked. It does this using the previously defined DisplayInfo function which will will also assign to main_btn here. If you'll remember, DisplayInfo used the location_text variable.

item_mc.species_txt.text = species.firstChild.nodeValue;
item_mc.main_btn.location_text = location.firstChild.nodeValue;
item_mc.main_btn.onRelease = DisplayInfo;

This is straight-forward assignment. This important part is just seeing how the text is referenced from the XML object - or at least from the variables we have here that each represent a part of that object. As text nodes and CDATA, the text exist as its own node as a child of either species or location. Also, as such, the nodeValue property is what retrieves the text associated with those nodes. So in order to get that text, firstChild.nodeValue is used on each element.

Having set those, there now exists a new fully functional item within our menu. It sports the name of a species of squirrel (assigned to a text field over the button) and when clicked will display that particular squirrel's location information in a separate dialog (sending the text field. of that dialog text defined in the button under location_text). All that remains is loading the XML and putting it into action.

Loading the XML. This should be nothing new. We already did this earlier. The only difference here is that a function is called from the onLoad event which creates the menu desired. Here's the script:

var squirrel_xml = new XML();
squirrel_xml.ignoreWhite = true;
squirrel_xml.onLoad = function(success){
if (success) CreateMenu(this);
else trace("Error loading XML file");

An XML instance is created, the white space is set to be ignored, the onLoad is defined and finally the actual XML document is set to load into the XML instance which will ultimately set off the chain of events that makes what is the squirrel finder. Above an error message is traced if the XML didn't load properly. This will only be seen when working on the movie from within Flash. It will be ignored when viewing the movie on the web (so there, it really serves no purpose).

An Alternate Route
Lets step back a little to the CreateMenu function and the loop that handles each item as it is added to the menu. This particular approach makes sole use of the firstChild and childNodes properties of XML nodes. However, Flash provides more ways to reference XML than just those two. Using other properties, well, namely nextSibling, we can modify the function a little to perform the same action but through a different means.

The current approach cycles through each item in the menuitem element's childNodes array using a for loop. This marks a position in the array and walks through it accessing the next item in the array upon each iteration of the loop. The procedure involves child access through parent.

A different procedure can be implemented - sibling access from another sibling. What this entails is taking the first child of any set of children and continuing through each following sibling until no more remain.

[ items via childnodes vs siblings ]

This approach uses the nextSibling property to traverse all children and gets rid of the parent reference altogether (aside from using the parent to get a reference to the first child to begin with). But how do you handle this? Surely not from a for loop? That's right; not a for loop but a do..while loop. Here's how that would be set up:

var currentSibling = targetParentNode.firstChild;
do {
// ... actions on currentSibling
} while (currentSibling = currentSibling.nextSibling);

You start off with the first sibling in the set of children of targetParentNode. The do portion of the do..while loop then executes allowing you to operate on that particular sibling immediately. Once that is complete the while condition is checked. This while condition actually does two things. It sets and checks. First currentSibling is assigned to its own nextSibling. This is what will give you the next child in the set. Assuming this currentSibling is valid (i.e. you're not at the last sibling who has no next sibling) then the while loop will loop back through the do block. Otherwise it will terminate and continue with the rest of your script.

The do..while loop, however slick, is not without its shortcomings. Namely, it does not keep an index count of which particular child you're working with. The for loop, for example, gave you an index representing a position in the childNodes array (via the variable "i"). This can be disadvantageous. No one's stopping you from creating your own within the loop. A simple i starting at 0 prior to the loop and and a i++ at the end of a do block will give you this, but is it worth it then? You might as well just use a for loop then. Then again, is it ever worth it? You may never use a do..while to access children this way; it may seem confusing or just unconventional. Maybe, but it is an alternative approach and worth noting.

Here is what the CreateMenu function would like using a do..while and nextSibling to access the squirrel finder menu's items.

function CreateMenu(menu_xml){
var currItem = menu_xml.firstChild.firstChild.firstChild;
do {
if (items[i].attributes.type == "squirrel") {
var species = currItem.firstChild;
var location = species.nextSibling;
var item_mc = menu_mc.attachMovie("menu_item","item"+item_count, item_count);
item_mc._y = item_count * item_spacing;
item_mc.species_txt.text = species.firstChild.nodeValue;
item_mc.main_btn.location_text = location.firstChild.nodeValue;
item_mc.main_btn.onRelease = DisplayInfo;
} while (currItem = currItem.nextSibling);



kirupa.com's fast and reliable hosting provided by Media Temple. flash components
The Text Animation Component for Flash CS3
Check out the great, high-quality flash extensions. Buy or sell stock flash, video, audio and fonts for as little as 50 cents at FlashDen.
Check out our high quality vector-based design packs! Flash Effect Components
flash menus, buttons and components Digicrafts Components
The best flash components ever! Entheos Flash Website Templates
Upload, publish, deliver. Secure hosting for your professional or academic video, presentations & more. Screencast.com Purchase & Download Flash Components
flash components Free Website | Make a Website
Streamsolutions Content Delivery Networks Learn how to advertise on kirupa.com