Introduction to XML in Flash
       by senocular

Navigation Through Helpful XML Properties
So far we've seen that XML nodes in Flash form have attribute objects and child nodes arrays stored as properties represent their structure. Flash ActionScript provides some additional properties added to XML nodes to help make navigation through it a little more easier. Here's a list of XML structural properties you can reference off of XML nodes.

Property Represents
XML Nodes
attributes An object containing attribute variables assigned to this element.
childNodes** An array containing all child nodes belonging to this node.
parentNode* This node's parent node.
firstChild* The first child in this element's childNodes,
or childNodes[0]
lastChild* The last child in this elements childNodes,
or childNodes[childNodes.length-1]
nextSibling* The node after this node in the parent's childNodes array.
previousSibling* The node before this node in the parent's childNodes array.
*Read-only and can only be checked, not directly set.
**Altering element order in this array will not be reflected in the XML instance.

Together, these properties provide the groundwork for you being able to navigate through your XML.

Of course seeing the properties, and reading and understanding what they represent is one thing. Being able to use them is a whole new slice of cheese. Making proper use of these properties is really what makes XML so difficult to deal with in Flash. We'll work through a little of that now but the Flash examples given later on will provide a better understanding of using them more effectively and in context.

The first thing to remember is that an XML instance represents a single node in which the rest of the XML is defined. That means that your XML instance and the document root node of your XML are not the same thing. The root node is actually a child of the XML instance. Since there should be only one root node (DOCTYPE and XML declarations are not considered nodes and are not accessible as children), that means your root node would be the first child of the XML instance. Given the XML instance my_xml, the root node would be:

my_xml.firstChild

From here, you can then start accessing your XML as needed.

Now, you'll notice that even just getting to the document root of an XML document through an XML instance requires using firstChild. What do you think happens when you want to get to the first child of the first element in your document root? Consider the following XML:

<mydocuments>
<mypictures>
<family>
<image title="Sister laughing" />
<image title="Brother laughing" />
<image title="Mother beating me" />
</family>
<vacation location="Myrtle Beach">
<image title="Sun bathing" />
<image title="Walking the dog" />
<image title="Swimming" />
<image title="Getting eaten by shark" />
</vacation>
<girls />
</mypictures>
</mydocuments>

Now assume this is the XML content of the my_xml variable in Flash. The first child of the first element in the document root is family (where mypictures is the first element in the document root). So, in order to reach the family node in my_xml, you would use:

my_xml.firstChild.firstChild.firstChild

Already you can see the complexity and confusion that's just starting to unravel. If it takes that much just to get to the first pertinent element in a simple XML document such as the one above, imagine the paths needed to get to things in a more complicated XML document. How are you ever to keep track?

Variables. Variables are the key to success and understanding when using XML. Variables and loops. Looping gets you through element children and variables provide you a way to give descriptive names to abnormal paths such as the one given above. What's easier to understand? my_xml.firstChild.firstChild.firstChild.firstChild or family.firstChild? Saving the original path in a family variable (as it represents the family element) you get yourself a clearer understanding in the reference to the specified image element.

When using loops, you would typically use the childNodes array. Then, just like with any other array, you would loop through each element performing whatever task is needed on each. For example, to loop through all the image elements in vacation, you could use:

var family = my_xml.firstChild.firstChild.firstChild;
var images = family.childNodes;
for (var i=0; i<images.length; i++){
currImage = images[i];
}

Using the attributes object, you could then access the titles of each and trace them in the output window

var family = my_xml.firstChild.firstChild.firstChild;
var images = family.childNodes;
for (var i=0; i<images.length; i++){
currImage = images[i];
trace(currImage.attributes.title); // trace each images' title
}

Lets say you then wanted to go about looping through the vacation images. How might you go about that? Well, you could use a similar path to get to vacation as you did with family. Only with vacation, the last child reference would have to be from the childNodes array since vacation is neither the firstChild nor the lastChild of mydocuments.

var vacation = my_xml.firstChild.firstChild.childNodes[1];

However, since family has already given us much of that path already, nextSibling can be used to get to vacation directly from family.

var vacation = family.nextSibling;

Unlike the child reference properties, the sibling properties stay within the same element scope being able to reference other nodes which share the same parent (in this case mypictures) as the node from which its being used. So, after going through the family image elements, you can go through vacation images using:

var vacation = family.nextSibling;
var images = vacation.childNodes;
for (var i=0; i<images.length; i++){
currImage = images[i];
trace(currImage.attributes.title); // trace each images' title
}

The following provides a more visual representation of what each property represents in regards to a vacation node within in an XML file.

[ xml references in respect to the vacation element ]

You can see that the vacation node has a wide array of direct access when it comes to referencing other nodes within the XML in respect to its location using those properties available to it. The parentNode property references mypictures, the element in which it exists; previousSibling and nextSibling references the child nodes next to vacation within that parent node on either side of itself (a.k.a. "siblings" like brothers and sisters). We saw how family's nextSibling was vacation. Using vacation's previousSibling, you can go back up to family. And then of course you have firstChild, childNodes, and lastChild provide access to vacations own children, its image elements. Parents, siblings, children, XML just asks to have a family tree written in it, doesn't it?

There are yet some other properties which you can use to find out more about your XML and its nodes. These don't necessarily help you navigate through your XML so much, but they provide important information nonetheless. They are as follows:

Property Represents
XML Nodes
nodeName The node's name. This is the tag name of an element node and null for other nodes.
nodeType*

A numerical value representing the node's type:
1 = Element
3 = Text Node (or CDATA Section)

nodeValue The node's value. This is text for text nodes and CDATA and null for elements.
XML Instances
xmlDecl XML's declaration
example: <?xml version="1.0"?>
docTypeDecl XML document DOCTYPE declaration
example: <!DOCTYPE greeting SYSTEM "hello.dtd">
loaded True or false depending on whether or not the last load() command has successfully completed for the XML instance.
status

A numeric value representing parsing errors during Flash 's attempts to convert XML text into the ActionScript XML object. They are as follows:

0 No error; parse was completed successfully.
-2 A CDATA section was not properly terminated.
-3 The XML declaration was not properly terminated.
-4 The DOCTYPE declaration was not properly terminated.
-5 A comment was not properly terminated.
-6 An XML element was malformed.
-7 Out of memory.
-8 An attribute value was not properly terminated.
-9 A start-tag was not matched with an end-tag.
-10 An end-tag was encountered without a matching start-tag.

*Read-only and can only be checked, not directly set.

We've already seen nodeName and nodeValue before, but nodeType is a new one. It helps you distinguish elements from text nodes. Other properties listed are for XML objects specifically and not the nodes they contain. The first two, xmlDecl and docTypeDecl let you extract an XML document's declaration and doctype which are not, technically, otherwise included as elements in the XML structure (at least not in Flash). The other two, loaded and status, just help determine information about loading and parsing XML, whether or not they were successful.

With all these properties out of the way, we can start getting into some examples which make practical use of them, hopefully in a comprehensible manner.


 




SUPPORTERS:

kirupa.com's fast and reliable hosting provided by Media Temple.