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