Search

E4X

I’ve been working with something recently that’s made me reconsider my stance on JavaScript as a sensible language. It’s historically been the red-headed stepchild of dynamic scripting languages and for good reason:

  • The standard library is a pitiful thing, indeed.
  • Writing in anything resembling an object-oriented style involves some pretty goofy hacks to get inheritance and public/private access working
  • Client-side web code has to be riddled with hacks and workarounds to make any non-trivial code work on all major platforms. Hell is other browsers.
  • Like PHP, it’s widely used by the cut-and-paste school of people needed to make their website do that shiny thing the boss wanted. There’s a lot of really awful code out there as a result- enough to give the language itself a bad rap.

If you look at JavaScript from a pure language standpoint, it’s actually not too bad. It’s weakly typed and interpreted, which always lend themselves to rapid development. Its object literal notation, JSON, is clean and consise. Functions are first class objects, complete with closures. It supports inline regular expressions, with a reasonably large subset of Perl5’s functionality.

And now, with E4X, it’s actually done one better than Python, Ruby, and their ilk. Well, at least where anything related to XML is concerned.

E4X (ECMAScript for XML) is a language add-on to JavaScript that provides a very clean native syntax for querying and modifying XML. You can create XML objects from strings or inline as a primitive type and do complex operations on them in very few lines of code. At the moment, forgot about using this on your website: the only browser out there supporting E4X is Firefox 2.0, using the partial implementation in SpiderMonkey. However, Mozilla’s Java-based Rhino engine has a full implementation as of release 1.6-r2 and is well worth considering as a server-side or embedded scripting environment.

Code speaks louder than words, so let me present some quick examples to demonstrate how powerful this stuff is:
First, let’s define an XML object. We just drop the sucker inline; they’re now a primitive type, like regular expressions in Perl.

js> var factbook = <ninja>
<fact confirmed="true">Ninjas are mammals</fact>
<fact confirmed="true">Ninjas fight all the time</fact>
<fact><purpose>Flip out and kill people.</purpose>
      <purpose>Make burgers</purpose>
</fact>
<sighting confirmed="true">Royal Place</sighting>
<sighting confirmed="false">Taco Hell</sighting>
</ninja>;

Querying for all direct fact elements is as simple as:

js> factbook.fact
<fact verified="true">Ninjas are mammals</fact>
<fact verified="true">Ninjas fight all the time</fact>
<fact>
  <purpose>Flip out and kill people.</purpose>
  <purpose>Make burgers</purpose>
</fact>

Or even all purpose elements somewhere within the root’s children:

js> factbook..purpose
<purpose>Flip out and kill people.</purpose>
<purpose>Make burgers</purpose>

Adding a new elements into the whole shebang behaves according to the principle of least surprise.

js> factbook.fact[2].purpose += <purpose>Honor!</purpose>
js> factbook
<ninja>
  <fact confirmed="true">Ninjas are mammals</fact>
  <fact confirmed="true">Ninjas fight all the time</fact>
  <fact>
    <purpose>Flip out and kill people.</purpose>
    <purpose>Make burgers</purpose>
    <purpose>Honor!</purpose>
  </fact>
  <sighting confirmed="true">Royal Place</sighting>
  <sighting confirmed="false">Taco Hell</sighting>
</ninja>

Hey, what about all elements that have the confirmed attribute set to true?

js> factbook..*.(@confirmed == 'true')
<fact confirmed="true">Ninjas are mammals</fact>
<fact confirmed="true">Ninjas fight all the time</fact>
<sighting confirmed="true">Royal Place</sighting>

Consider what you’d have to get that done accessing XML at an object level with DOM, and you start to see why this kicks major ass.

var elements = document.getElementsByTagName('*');
var results = [];
for(var i=0;i<elements.length; i++){
    if(elements[i].getAttribute('confirmed') == 'true')
        results.push(elements[i]);
}

I’ve barely scratched the surface of E4X, but this should give you a taste of what’s possible. This stuff is cool enough to make me actually exciting about working with JavaScript and if that’s not a landmark in language development, then I don’t know what is.

Write a comment