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.
|