Filed under: actionScript, appCoreLib, development, e4x, flash, flex, regexp, xml
A powerful yet elegantly simple construct
As a flex developer, I consider XML as a necessary and highly useful language for various aspects of RIA development. There is a myriad of uses including but not limited to:
- external URL storage for links
- non-embedded content loading of jpgs, gifs, pngs and other swfs
- internal URL pointers for RESTful type services
- incoming service response objects
- application initialization data (e.g. dataProviders, default settings)
- and the list goes on
That is all well and good. But the problem is that if you don’t fully understand how to traverse an XML object and understand what it does when using e4x to access, then you are not making the most of this simple yet powerful development structure. The next problem lies in that there is very poor documentation on e4x in respect with the ActionScript XML class.
Truly understanding what the XML Object & e4x does
Adobe did a decent job of showing you how to traverse an XML object via e4x and then seeing their simple little trace statements. But what they failed to do was to give you useful examples of how to use that output and turn it into ActionScript-friendly objects.
Grabbing an XML node’s attribute
We have all probably used the following to get a value from an attribute from an XML node:
var o:Object = someXMLObject.@someAttribute; //o is now an XMLList
The issue with this example is that o is an instance of an XMLList. In order to fully make use of the value inside that singular attribute (why it turns it to an XMLList when specifying that node’s attribute expecting a singular value, I have no idea) we have to cast that value to what we want. Here are a few examples:
var s:String = String(someXMLObject.@someAttribute);
var n:Number = Number(someXMLObject.@someAttribute);
Easy!
Constructing an XML object from within ActionScript
Most everyone has probably used the following to construct an XML variable in AS3:
var x:XML =
<node someAttribute="value">
<subNode anotherAttribute="value"/>
<subNode>value</subNode>
</node>
Doing a trace on that would yield the expected XML to output to an XML string, retaining the nested structure and brackets. But using the new XML() constructor can yield some different results, some unexpected and not entirely useful.
var x:XML = new XML("node"); //traces "node" and not <node/>
So how would one dynamically construct a new XML object when not knowing the node name?
var x:XML = new XML("<" + dynamicValueForNodeName + "/>");
I don’t like the above setup. Its a messy read. Certainly there is another option?
var x:XML = <genereicNodeNameToBeChanged/>;
x.setName("newNodeName"); //traces <newNodeName/>
While this is documented, they really don’t touch on it at all in their given examples.
Setting values to nodes
If you wanted to put a subNode inside a parentNode you’d probably use syntax such as:
var x:XML = <node/>;
var x2:XML = <subNode/>;
x.appendChild(x2); //which yields <node><subNode/></node>
That is probably the most common usage of appendChild(). But did you know you can append values as well? Not just subNodes but also non-nodal values:
var x:XML = <node/>;
x.appendChild("someValue"); //traces <node>someValue</node>
Again, this is very useful but not really touched upon by the documentation.
Finding values using the . syntax
One of the nicest features about e4x is that you can rapidly find value(s) nested deep within the XML by using the “dot” syntax. I will abstain from listing an example here as there are numerous examples on the documentation site. But did you know that you can make multiple inquiries on an XML structure within the same line of code?
arrayElementType = String(item.metadata.(@name == "ArrayElementType").arg.(@key == "" || @key == "type").@value);
This eliminates the need to make multiline inquiries by getting an XMLList from one e4x boolean operation, then repeating down the line until you have driven down into the specific node you are looking for.
Using this new-found knowledge
Though you may or may not have known about some of these little tricks, you might be wondering, “so where do I use this”. A few posts back I eluded to the fact that I was developing an XML-to-ActionScript translator for AppCoreLib. The translator would then be able to quickly take in an XML response from a web service and spit back a useful ActionScript object of a specified class with little work involved by the responder. In order to do this, I have to make major use of XML and specifically the XML spit out by the describeType method. It means that I not only have to traverse the XML object, I also have to dynamically construct XML objects to be sent back. After the first build, I was a little miffed that I had some hard to read, and plain ol’ ugly ass code. I wanted to fully immerse myself in what the XML object and e4x had to offer.
If you have some not-so-well-documented tips and tricks for XML and e4x, send them along and I will add it to the post.
14 Comments so far
Leave a comment
<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <pre> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Where is this XML-to-ActionScript translator creature of which you speak. Would love a whirl around the floor with her no matter how ugly her code be.
thx
Comment by SteveLearnsFlex Wednesday, February 27, 2008 @ 9:31 pmWell one version resides in AppCoreLib under the ClassUtil – http://code.google.com/p/appcorelib/source/browse/trunk/src/appCoreLib/utils/ClassUtil.as
But it is incomplete and needs further work. The current version I am working on is in my little toybox project. I can send you the source if you like. Shoot me an email if you want the current source: jwopitz at gmail dot com
Comment by jwopitz Wednesday, February 27, 2008 @ 9:34 pmOn the non-node subitem:
In the case of
nodeContents
the nodeContents is seen by AS as a node, hence myNode.firstChild will give you back nodeContents… So following the logic of AS, it is only normal that appending a non-node value to a node will result in that node getting filled with the appended value.
This is a good post though, very usefull for people who still have their doubts on the best ways on how to use the (a bit blurry) XML and E4X in AS3.
Comment by Gerrit Wednesday, February 27, 2008 @ 10:00 pmMy case was:
\nodeContents\
Forgot that the tags would be stripped
Comment by Gerrit Wednesday, February 27, 2008 @ 10:12 pmInstead of:
var x:XML = new XML(”");
You can use the {} operator to do
Comment by MikeZ Wednesday, March 19, 2008 @ 6:56 pmvar x:XML = new XML();
If you want to use a variable as node name, you can use the {} notation. For attributes, you have to use the [].
//——-
var nodeName:String = “myNodeName”;
var xml:XML =
var attributeName:String = “hello”;
xml.@[attributeName] = “world”;
mx.controls.Alert.show( xml.toXMLString() );
//——-
Comment by simon Friday, April 18, 2008 @ 3:21 pmshould read var xml:XML = ( without the spaces… that part got cut off
Comment by simon Friday, April 18, 2008 @ 3:22 pmforget it.
Comment by simon Friday, April 18, 2008 @ 3:23 pmI have a question about XML class. I’m trying to acces tag with name “fade-in” . But it’s just not working, becouse of that “-” sign. I also tried with elements(”fade-in”).
Is there any elegant solution for this?
Regards,
Comment by Grega Thursday, June 19, 2008 @ 3:24 pmGregor Čepek
what is the syntax you are using to get at it? I haven’t experienced this problem however I also haven’t had a need to access a node named with a hyphen. I normally use camelCase.
Comment by jwopitz Thursday, June 19, 2008 @ 3:51 pmGregor:
You can enclose it in brackets like this ["fade-in"] and it seems to work. At least for me.
Comment by Sarah Monday, July 28, 2008 @ 12:17 pmYou can also use curly brackets to dynamically assign XML properties in a more concise way:
var dynamicValueForNodeName :String = “node”;
Comment by Nathan Friday, January 2, 2009 @ 8:57 pmvar xml:XML = ;
trace(xml.toXMLString());// traces “”
Oops, wordpress ate my code. Sorry. Let me see if this works:
Comment by Nathan Friday, January 2, 2009 @ 8:59 pmvar dynamicValueForNodeName :String = "node";var xml:XML = ;
trace(xml.toXMLString());// traces ""
Aaargh! My apologies. I don’t know how to insert curly braces into this post.
Here’s a link to the site where I think I learned this if you want to find what I’m talking about. Search the page for “Dynamic XML definitions”.
And here goes one last try to post the code here:
Comment by Nathan Friday, January 2, 2009 @ 9:03 pmvar dynamicValueForNodeName :String = “node”;
var xml:XML = \;
trace(xml.toXMLString());// traces “\”