Sign In/My Account | View Cart  
advertisement


Listen Print Discuss

Introducing E4X
by Kurt Cagle | Pages: 1, 2, 3, 4

In this particular example, when the document initially loads, it asynchronously retrieves the atom feed from the server via the populate() function using an XMLHttpRequest call. The goal here is to minimize the amount of processing of the feed as a DOM, so here that process is handled by using the http.responseText method to get the feed as text. The Mozilla E4X implementation has a few serious limitations, one of the biggest of which is its inability to parse XML declarations that start with <? and end with ?>. Thus, it is necessary to run a quick regular expression to remove all of these:

var data = data.replace(/<\?(.*?)\?>/g,"")

Namespaces in E4X are something of a headache, for much the same reason that they are a headache in XML in general. However, it is possible to change the default namespace and work within the context of that namespace without needing to create a formal namespace declaration or use prefixes. In order to retrieve the feeds from the relevant returned document (which includes various HTTP request and response headers as part of the package), the default namespace was set to Atom as "http://www.w3.org/2005/Atom":

    default xml namespace="http://www.w3.org/2005/Atom";
    var feed = new XML(data);

Once so declared, it becomes possible to switch back and forth between then Atom namespace and the XHTML namespace, jumping from reading data appropriate to each entry to making new option elements for that entry:

    for each (entry in feed..entry){
    default xml namespace="http://www.w3.org/2005/Atom";
    var title = entry.title.toString();          
    var id = entry.id;
    default xml namespace="";
    var option = <option value={id}>Introducing E4X</option>.toXMLString();
    selectNode.innerHTML += option;
    }

Note the use of the toString() and toXMLString() methods. E4X exposes a limited set of methods on E4X XML() and XMLList() objects (you don't have the same ability to assign methods to E4X objects that you do with ordinary objects for this reason). A reference such as entry.title actually returns an XML node; if this is used as part of a string expression then the JavaScript engine will automatically recast the node to its text value, but sometimes it is better to make this explicit via the toString() method (you could also do ""+entry.title to do the casting, but that operation isn't always obvious when looking at code). Similarly, the toXMLString() method will serialize an XML() node as XML content, while applying toXMLString() to an XMLList() object will return a serialized collection of nodes.

The mapping to the default namespace prior to the option will set the namespace to the namespace of the containing object, which in this case is the <select> node, if passed to the innerHTML property.

One of the more useful aspects of JavaScript as a language is the use of closures, in which variables that are defined at one point, then used within a function defined in the context of those variables, will continue to hold the values previously assigned so long as the function remains in scope.

This is used to good effect in the internally defined selectFeed() function. The feed is referenced within the function, as well as displayNode and linkNode, which defines the display area for a selected entry's content and a button for launching the original page in a second window. One interesting consequence of this is that because the selectFeed() function is then assigned at that point to the selection box listing the titles, the feed itself remains in memory, but is completely inaccessible to anything beyond the selectFeed() function. Admittedly, in this case it doesn't make that much difference (determining the feed is relatively simple), but from a security standpoint this provides a layer of protection on potentially sensitive information.

var selectFeed = function(){    
    default xml namespace="http://www.w3.org/2005/Atom";
    var entry = feed..entry.(id==selectNode.value);
    var link = entry.link.(@rel=='alternate').@href.toString();        
    var content = '<div xmlns="http://www.w3.org/1999/xhtml"><h2>'+
         entry.title+'</h2>'+entry.content.text().toString()+'</div>';
    var content= content.replace(/<\?(.*?)\?>/g,"")
    default xml namespace="http://www.w3.org/1999/xhtml";
    displayNode.innerHTML = content;
    linkNode.setAttribute("href",link);        
    }; 
    selectNode.addEventListener("change",selectFeed,false);

I wanted to include the link to the source not only because it's a logical piece of a feed viewer, but because it's useful to illustrate an attribute filter in E4X. In Atom, a given entry may have more than one link associated with that entry. The rel="alternate" link is typically the one that contains a reference to the relevant web page that the resource came from initially (and as such there is always only one such alternate link). The expression entry.link.(@rel=='alternate').@href thus retrieves from the link collection the link for which the @rel (relationship) tag is set to "alternate". The expression within the parentheses here is (more or less) JavaScript; the @rel retrieves the rel attribute relative to the link collection and compares it to the string 'alternate' (note the double equal signs). This is a filter, just as var entry = feed..entry.(id==selectNode.value); in the previous line is a filter.

A screenshot of the "app" is shown in Figure 1.

Metaweb Screen Shot
Figure 1. Metaweb Screenshot

At the end of this method you have the expression linkNode.setAttribute("href",link). This is a DOM statement, because linkNode is a DOM element, not an E4X element. At this stage, while one of the main goals of the E4X process was to create a simpler, more efficient way of working with document objects, this has not been realized in any significant way.

By the way, it is possible to convert an E4X object into a DOM tree and vice versa, though these are comparatively expensive operations. The function eNode2dNode performs the conversion one way, converting an E4X object into the root node of its own DOM-based document, while dNode2eNode makes the conversion in the other direction:

var eNode2dNode = function(eNode){ 
    var str = eNode.toXMLString(); 
    var doc = (new DOMParser()).parseFromString(str,"text/xml"); 
    return doc.documentElement.cloneNode(true); 
    }
    
var dNode2eNode = function(dNode){
    var str = (new XMLSerializer()).serializeToString(dNode);
    var eNode = new XML(str);
    return eNode;
    }

E4X and JSON

It is not my wish to deprecate the importance or value of JSON in this article (well, not much anyway). JSON represents a minimally sufficient platform for information interchange within most browsers, and as such realistically will be around for quite some time (especially as Microsoft's Internet Explorer does not look like it will be adopting the most recent JavaScript changes any time soon).

However, it's worth noting that a lightweight XML protocol, LINQ, likely will be migrating to IE with its next release. While differing somewhat in syntax from E4X (and having a considerably broader role), LINQ will most likely be doing much the same duty in IE that E4X does in Firefox and Flash—providing a way of using XML easily and cleanly without having to use the rather cumbersome mechanism of DOM. Given the increasing dominance of XML as a messaging and transport protocol on the server and between server and client, the use of LINQ does open up the notion that you can take advantage of the rich characteristics that XML has to offer without having to complexify your code with DOM manipulation.

At a minimum, if you are specifically targeting the frameworks where E4X is supported, you should take some time to investigate the technology, especially when dealing with the increasingly syndicated nature of web technologies. Combining E4X and Atom, for instance, opens up all kinds of interesting potential usages, especially given the increasing role that Atom is playing as a data transport protocol for companies such as Google. While it is possible that you'll see more companies exposing JSON services, I personally see XML-based Atom services growing far faster, and in that case the use of a native XML datatype just cannot be beat.

Kurt Cagle is an author, research analyst with Burton Group, technology evangelist, information architect, and software developer specializing in web technologies. He is the webmaster for XForms.org. He lives in Victoria, British Columbia, where he's working on the open source x2o data server.


Comment on this articleShare your experience in our forums.
(* You must be a
member of XML.com to use this feature.)
Comment on this Article


Titles Only Titles Only Newest First
  • #1 Carpet Rugs Upholstery Cleaning West Los Angeles 1-310-925-1720
    2009-06-11 15:00:55 whats [Reply]

    #1 Carpet Rugs Upholstery Cleaning West Los Angeles 1-310-925-1720
    L.A Carpet Care call 1-323-678-2704 Steam or dry Cleaner - Carpet Steam or dry cleaning, Deep Shampoo Carpet Cleaning, Area Rugs cleaning, Mattress Cleaning, Upholstery furniture Cleaning, curtain cleaning, Green Organic Carpets Cleaning.
    Los Angeles Carpet Cleaning Company Non-toxic Cleaning, Safeclean organic cleaning Los Angeles, California. Carpet cleaning Los Angeles,CA: We provide rug cleaning, upholstery cleaning, wood floor refinishing & maintenance, flood & water damage restoration, air duct cleaning and much more. LA Carpet Cleaning The Main Los Angeles Local Carpet Cleaners


  • you're fired
    2008-02-26 03:51:43 jemptymethod [Reply]

    I'm absolutely flabbergasted by the amount of misinformation contained in this article, particularly regarding JSON. You don't have to write your own parser for PHP, they've been in existence for 2.5 years before you wrote this drivel. I don't know if it's deliberate misinformation because JSON is considered in competition with XML, or just plain ignorance or carelessness. But if I were a CTO and you worked in my department, and I'd read this article, I'd have fired you on the spot. Shame on O'Reilly for not properly vetting this: this article should be pulled, because it reflects very poorly on O'Reilly

  • Errors
    2007-12-17 10:22:56 altjeringa [Reply]

    The author addresses the question of wire transfer differences between JSON and XML adequately but fails to address the marshalling/unmarshalling speed aka serialization cost. JSON is native Javascript and can be converted to javascript objects 10s to 100s of times faster than XML and can be is produced on the server with at minimum the same speed as XML. ( if you are using DOM methods instead of strings on the server json is faster ).


    Another misnomer is that JSON is Ruby. While the rails platform obviously popularized it, it neither invented JSON nor is JSON the native data serialization for Ruby. It to uses a parser just as does everybody else. The closest thing to JSON I've actually seen is Python which isn't even mentioned here.


    E4X is a nice and simple method of dealing with XML in javascript, and it would be great minus the fact that it can't be used anywhere. The tutorial is useful but the author should stick the tutorial and avoid the editorializing.

  • Array programming
    2007-11-30 13:32:40 iconara [Reply]

    (the previous post, titled 'Arrr', was posted by me I must have accidentally pressed the wrong button, or the pirate in me wanted to have his say)


    To me, the most important difference between working with plain javascript object structures (such as JSON) and working with XML using E4X is that the latter is an example of array programming.


    Things like "html.body.p.a" aren't possible to express in most programming languages. The important thing is that in E4X that expression means something completely different than the same expression in the context of a regular JSON structure.


    In E4X "html.body" returns a trampoline object (XMLList), which asks all the elements in it for their "p" children, returning yet another trampoline, which asks all it's elements for their "a" children. if the expression is "html.body.p.a.text()" the text method is called on all "a" nodes and a list of all the results is returned. When working with JSON, "html.body" returns one object, or a list of objects. If it's a list we have to write a loop to do something with the children. Just getting the text content of all "a" nodes would require three nested loops (depending on the actual data structure). Of course the code behing E4X uses loops, but the point is that we don't have to.

    • Array programming
      2007-12-01 10:39:36 Kurt Cagle [Reply]

      Re Arrr,


      This is one of the biggest difficulties I have in getting AJAX developers comfortable with e4x. As a language, e4x looks like JSON, but it acts more like a form of SQL, because you are essentially performing set manipulation rather than object manipulation. This is a not inconsiderable conceptual leap, and one that can even occasionally throw people that are comfortable working with XML.


      One way that I like to think about the distinction is that to object JavaScript, applying a list operation on a particular named property will generate an error. Applying the same operation on an E4X will be valid, because any named object exposes both the XML() and XMLList() interfaces - an object is a list of one element.


      I'm banking on XQuery becoming increasingly prevalent on that server, which should have as one immediate consequence the resurgence of XML as a messaging format to the client, which means that the ability to work with XML on the client will continue to climb. The tools that exist now - XPath in particular, have received only indifferent support in browsers (one of the big failings that I see in Firefox is that they don't wrap the awful, cumbersome W3C Xpath API in a more convenient package) and to a great extent works in a silo compared to the rest of JavaScript. E4X should help equalize that.




  • Prediction: It won't last
    2007-11-30 12:40:42 shogun70 [Reply]

    There is a JSON-to-XML Mismatch and to my eyes E4X pretends there isn't. It will create more pain than joy.


    Of course, I might be missing something.


    Seriously, would you use it unless you had to?


    • Prediction: It won't last
      2007-11-30 16:55:04 Dan Sickles [Reply]

      As stated in the intro, many databases and applications produce XML so that's what we have to deal with. All else being equal I'd rather work with JSON but I rarely control both ends down to the DB. It's interesting to note that couchdb switched from XML to JSON. I had written some e4x code against that XML but what I did with xul/e4x is much easier now with JSON and html ui frameworks. Scala does some interesting things with literal XML, like matching against elements, but with a more XPATH-like syntax for referencing xml objects. I prefer the e4x syntax. The javascript frameworks can leverage JSON, e4x and xlinq "under the covers". Anyhow, I think e4x will last as long as people keep putting XML on the wire.

      • Prediction: It won't last
        2007-12-01 10:52:35 Kurt Cagle [Reply]

        Dan,


        I think that the minor stream of XML coming from the server will be giving way to a flood soon; there's just too much going on in the distributed server space to not expect that to happen.


        That doesn't obviate JSON as a delivery mechanism; there are places where JSON is generally the most efficient way of sending content, and JavaScript is geared towards JSON while e4x support for the most part still exists mostly in islands. However, I think of that if any database produced only one format (either XML or JSON) they are being foolish in the extreme.

        • Safari 3.0 {E4X & XQuery}
          2007-12-18 16:18:47 frederick.c.lee [Reply]

          Greetings:
          I'm the sole Mac OS X developer for a Microsoft shop here in Silicon Valley. Their clients are increasingly demanding OS X support (about time).


          One of my assignments is to interface with Entourage/Mail Server, with XML being the data vector. I must support Firefox 2+ & Safari 3+.


          I've used Firefox 2 on an earlier project because of its support for E4X.


          Question: Does Safari 3.0 support E4X? I suspect it does, yet there's no DIRECT answer. And for that matter which JavaScript version does Safari 3.0 support? Firefox 2+ supports JavaScript 2.0.


          And, where's XQuery?


          I've read about it, sound exciting...
          ... but I don't know which browsers support it; and to that effect, whether Apple's Web Kit supports E4X & XQuery.