Is E4X Strong Enough to Obviate the Need for an Object Layer?



In many applications, a common task is to load data as XML, and then translate this into 'objects' that are used by the program. You can see this kind of behavior in ComCenter, but I've also used it in many programs that use XML over the years.



Part of the reason I've done this is because using standard XML access methods whether it be through SAX, DOM, or some other method was awkward-it was much easier to create a class that represented each tag. You could then parse your XML(using one of the aforementioned methods) and instantiate objects and set object attributes. When you've finished this, you now have a tree of objects that basically reflects your XML tree. You also have an easier way of accessing properties-you can simply say MyObject.id=9 to reference the id attribute that might have been in a specific XML tag.

Usually reflecting XML into native programming objects wasn't too onerous, but even so, a number of XML packages evolved in the Java world that would do this sort of thing for you automatically.

Enter E4X. E4X gives you a concise notation that makes it trivial to access XML tags and attributes. Its as easy as using the object.property reference I used above. Its so easy, in fact, that I wondered for the first time if there was a point in creating an object representation of the loaded XML. Perhaps it would be better just to leave the data in ActionScript's XML Object and make updates to it there? E4X itself almost seems like it has created an object mapping for you-why make a representation of a representation?

After careful consideration I've decided to stick with an object representation (for the time being). This is mostly due to one issue: methods. Although E4X allows you to easily access various XML tag attributes; I often find my reflected objects contain specialized methods for dealing with each object's properties. I don't see an easy way of accomplishing this through E4X without creating an object mapping. (The only way I can conceive of this working through E4X is to build in a way of manipulating the data that the XML contains into the XML itself-and I'm talking about something stronger than XSLT here. If only eval() still wasn't broken!!!)

Just the fact that E4X makes you reconsider XML-object mappings is a testament to its strength.

2 comments :

Unknown said...

It's tempting to use the XML directly now with E4X, pass it around to the classes that need it etc, but I think there's still value in creating a strongly typed model that your application refers to.

If you ever decided to power your app without XML you'd be able to switch over without a global search and replace. You'd just need to modify the way in which your model objects were created.

In the end I think it all depends on the size and scope of your project. For small things, using XML directly with E4X is a very easy and straightforward way to go.

Unknown said...

I've worked fairly heavily with e4X on the Mozilla side, and tend to agree with your assessment about the object method limitation. Typically, the only way around it is to build a wrapper on the e4X object itself:

var E4X = function(e4x,props){
var _E4X = this;
this.e4x = e4x;
for (key in props){
_E4X[key] = props[key];
}
}

var xml = <test a="5" b="3"/7gt;;
var methods = {
sum:function(){
return parseFloat(xml.@a) + parseFloat(xml.@b);
}
}
var e = new E4X(xml,methods);

print(e.sum())
=> 8

Of course, such methods work on the instance at the point of submission (if the "xml" object above contained a reference to a child of the XML structure, then the methods would work on that entry point), though you could always test the node name prior to invoking the function and use polymorphism.

I believe that in the original e4x spec there was a call() method, but I don't believe it made its way into either Mozilla or ActionScript.