I have created an open source library that implements every array method for E4X XML lists in JavaScript named e4x-array-methods.js. The methods output XML as opposed to arrays to make the output directly usable with other XML. To get the array representation of an XML list, use slice. This returns XML when used to slice out ranges from XML but if no arguments are passed or a third argument is specified which is equivalent to true, it will convert an XML list to an array instead. For example, xmllist.slice(3, 5) returns an XML list and xmllist.slice(3, 5, true) returns an array.
Download
You can download e4x-array-methods.js at it’s github repository. If you wish to minify the library yourself, make sure that your minification tool supports the E4X used in this library. Rhino-based minifiers fail, throwing syntax errors, and /packer/ errantly minifies all of the public methods names preceded by .function::.
Example
The following example demonstrate the usefulness of having array methods for XML lists. If you want to try out the example in a JavaScript shell, make sure XML.prettyPrinting is set to false, which removes any unnecessary whitespace from xml.toString() and xml.toXMLString().
XML.prettyPrinting = false; // for simplifying the comparisons below var foo = <></>; // XMLList literal foo.push(<n>0</n>, 1, 5, 3, 2, 6, 4); foo.toXMLString() === "<n>0</n><n>1</n><n>5</n><n>3</n><n>2</n><n>6</n><n>4</n>"; foo.sort(function(a, b) { return a - b; }).toXMLString() === "<n>0</n><n>1</n><n>2</n><n>3</n><n>4</n><n>5</n><n>6</n>"; foo.filter(function(x) { // filter out integers less then 3 if (!(x < 3)) return true; }).toXMLString() === "<n>3</n><n>4</n><n>5</n><n>6</n>"; foo.slice(2, 5).toXMLString() === "<n>2</n><n>3</n><n>4</n>"; foo.splice(2, 1, <n>9</n>, <n>8</n>).toXMLString() === "<n>2</n>"; foo.slice(2, 5).toXMLString() === "<n>3</n><n>9</n><n>8</n>"; foo.pop().toXMLString() === "<n>6</n>"; foo.shift().toXMLString() === "<n>0</n>"; foo.shift().toXMLString() === "<n>1</n>"; foo.unshift(<bar/>); foo.toXMLString() === "<bar/><n>3</n><n>9</n><n>8</n><n>4</n><n>5</n>"; foo.map(parseFloat).forEach(function(n){ print(n) }) // prints NaN, 3, 9, 8, 4, 5 foo.some(function(x) { // some are greater than 5 if (x > 5) return true; }) === true; foo.every(function(x) { // all are numbers if (typeof x == "number") return true }) === false; |
Thanks for these, they will certainly come in handy in the future.
We developed a web server that sits on IIS, runs pure javascript (through SpiderMonkey) and uses e4x for templating. I implemented Array.prototype.mapXml and it has proven to be one of the most valuable methods in our arsenal. It allows us to write code like this:
It is easy to implement and hard to live without once you've used it.