PostCMS Blog
E4X gotchas
PostCMS now supports using E4X in server-side Javascript, for example when you're scripting a web template or web service. E4X provides a simple and elegant way to embed XML in Javascript without having to muck about with all that verbose DOM stuff.
For example, you can write:
http://www.xml.com/pub/a/2007/11/28/introducing-e4x.html
http://rephrase.net/days/07/06/e4x
var x = <category>News</category>;There a good tutorial on the Mozilla site, plus a few more listed below. But there are still lots of tricky little things that aren't very well documented. Here's a few of the gotchas we've discovered:
- To create a list of an arbitrary number of XML elements (called an "xml list"), you should use the following construct:
var x = <><foo>text1</foo> text2 <bar>text3</bar></>
Omitting the <>...</> tags will lead to a syntax error being reported. - Array indexes start at 0. Probably only confusing if you're used to Xpath, where they start from 1.
- E4X reserved words
var x = myXml.@attr-name;
are perfectly valid as far as E4X is concerned. However, they're NOT when you embed them in Javascript. You need to use the following syntax for javascript reserved words (eg. "id", "class", "delete", etc.) and attributes/names containing "-":
var x = myXml.@id;
var x = myXml.my-element;var x = myXml.@["attr-name"];
var x = myXml.@["id"];
var x = myXml["my-element"]; - insertChildAfter()
var x = <x><el/>;
You might expect the above to insert a <new-el/> element after the <el/> element. But in fact it silently does nothing. This is because "x.el" isn't an xml element, bul an xml list. The correct syntax is as follows:
x.insertChildAfter(x.el, <new-el/>);var x = <x><el/></x>;
x.insertChildAfter(x.el[0], <new-el/>); - Namespaces. In a similar fashion to xslt, the following will only find "div" elements in the empty namespace:
var divs = e4x..div;
So why is this a problem? Well, xhtml documents should contain a root-level xmlns="http://www.w3.org/1999/xhtml" attribute. This means that you have to specify a namespace in your "xpaths". One simple way I've found of doing this is as follows:var ns = e4x.namespace();
Other alternatives exist. the other alternative
var divs = e4x..ns::div;var divs = e4x..*.(localName()=='div');
doesn't work. It should according to the docs but... it doesn't.
Useful E4X links
http://wso2.org/project/mashup/0.2/docs/e4xquickstart.htmlhttp://www.xml.com/pub/a/2007/11/28/introducing-e4x.html
http://rephrase.net/days/07/06/e4x



