A few months back, I wrote a Director Online article about using the Flash Xtra to read XML data into Director. Now, I would never claim that this was the only way to work with XML; a fine Lingo alternative to the native XML Parser Xtra was created by Andy White six years ago and it’s still probably the best-known method for working with XML reliably. It’s even been extended, with the newer version (as well as the original) available through Shocknet.
But since my article was written in haste, I focused on the loading of XML data into Director and glossed over the actual access to the XML data. Since the XML object is not a Director list and because access to the data is through ActionScript properties executed in Lingo, that was probably a mistake on my part. A recent inquiry by Peter Wolf, who’d read the article, has prompted this attempt at explanation.
Here’s the sample XML document I’ll operate on:
<?xml version="1.0" ?>
<testnodes>
<item id="level0">This is Level 0</item>
<item id="level1">This is Level 1</item>
<item id="level2">This is Level 2</item>
<item id="level3">
<item id="level3.5">This is Level 3.5</item>
</item>
<item id="level4">This is Level 4</item>
<item id="level5">
<![CDATA[<a href="/">This is Level 5</a>]]>
</item>
</testnodes>
Refer back to my DOUG article to learn how to read in the file. The process creates an instance of a parent script, which can be assigned to an arbitrary variable. In the article, I named the variable doug; here I’ll just refer to it as x.
The XML data in the object is contained in a property named objXML. Typing put x.objXML.toString () in the Message window converts the XML data to a string and writes everything out.
The first node in the XML data is the testnodes container, which is the primary node for the XML document. It has 6 child nodes. You can determine that after reading this data in with the command put x.objXML.firstChild.childNodes.length. The firstChild reference is relative to the XML data, and points to testnodes. The childNodes refers to the children of testnodes.
If you’ve been confused by the whole goofy firstChild and nextSibling terminology in most XML references, don’t be ashamed. The people who came up with that scheme should be rounded up and shot. childNodes[0] is really all you need for firstChild because they mean the same thing. In the example above, you get exactly the same result if you type put x.objXML.childNodes[0].childNodes.length.
The first item in testnodes has both an attribute (within the opening tag for the item) and text between the opening and closing tag.
The item itself can be referred to as put x.objXML.childNodes[0].childNodes[0]. You can verify that by putting it (with the toString method following it) in the Message window and you’ll see both tags as well as the text between them.
Flash recognizes two node types: element and text nodes. The item nodes are element nodes. If you type put x.objXML.childNodes[0].childNodes[0].nodeType, you’ll get a result of 1.0000. Text nodes return 3.0000 (other types of XML nodes are assigned to 2 and other values).
The text between the opening and closing tags is technically another (text) node. The nodeValue property of the first item returns VOID.
The attribute (or attributes) of a node are accessed through a property of the same name, combined with the attribute name. In the items, there is an attribute named id. Typing put x.objXML.childNodes[0].childNodes[0].attributes.id returns "level0".
To get to the text between the tags, you need to go down another level. First, make sure there is another level. Typing put x.objXML.childNodes[0].childNodes[0].childNodes.length returns 1.0000. Then, check to see whether the node is an element or text node. If put x.objXML.childNodes[0].childNodes[0].childNodes[0].nodeType returns 3.0000, you’ve got text.
You can access the text with nodeValue. Typing put x.objXML.childNodes[0].childNodes[0].childNodes[0].nodeValue will get you "This is Level 0".
A simple change, and you can get the fifth item’s text as well: put x.objXML.childNodes[0].childNodes[4].childNodes[0].nodeValue will return "This is Level 4". Note that the last childNodes index value didn’t change, the items are referenced by the second childNodes level, the final one just accesses the text node within the item node.
To make it a little harder, let’s try to determine the correct reference to the id attribute that says level3.2. That’s the third child node of the fourth child node of testnodes. Remembering that all index values in Flash objects begin with 0, if you try put x.objXML.childNodes[0].childNodes[3].childNodes[2].attributes.id, then you got it right. x.objXML.childNodes[0].childNodes[3] is the fourth child of testnodes, childNodes[2]is its third child, etc.
Finally, let’s look at the results of the text data in the node with the id of level5. If you type put x.objXML.childNodes[0].childNodes[5].childNodes[0].toString (), what you get is URL-encoded data for the text within the CDATA brackets: "<a href="/">This is Level 5</a>". On the other hand, if you reference the data through the nodeValue parameter, you get non-encoded text: "<a href="/">This is Level 5</a>". This is useful if you need to pass text with links or tags in it, because otherwise the XML interpreter will attempt to render them into the XML structure.
Of course, this type of access isn’t limited to my own simple XML import implementation. They apply to any Flash XML object being manipulated in Lingo (or ActionScript, for that matter).
Drop me a line at blog at darrelplant.com if this has been helpful or if you have any questions!