One of the issues I’ve come across when dealing with XML in ActionScript 3 has been the inability to dynamically execute E4X queries. The need to do so arose several times, and one solution was to use RiaOne’s D.eval API. This solution is pretty robust; it’s a runtime parser/compiler for ActionScript code and it works pretty well. I have a couple of issues with it though. The first is that it’s like using an atomic bomb to kill a fly. When all you want to do is navigate through an XML document at runtime, a tool that can parse the entire ECMAScript specification seems like overkill. My second issue is that it’s a black box with hard to understand, diagnose, and catch runtime errors. At first, I thought that an implementation of just the E4X portions of the spec would provide a solution, but that soon led me into a labyrinthine maze of what to cut and what to keep. I wanted something a lot simpler and that’s where XPath 1.0 enters the picture.
One note on how to improve performance: position predicates in the form of
/document/element are much faster than boolean predicates in the form of
/document/element[@name = 'temp'].
How to use it
The entry point for the library is the
com.watchthosecorners.xpath.XPath class. It has two static methods and two instance methods that allow either the evaluation of an XPath query or the selection of a single node. Imagine we have the following XML document for use in our XPath queries (bear in mind that XPath uses 1 as its start index, not 0):
<document> <element>Some Value</element> <element>Some Other Value</element> </document>
The following snippet would retrieve the text value of an element. The evaluate method can return a string, a boolean, a number, or a node-set (an array of values):
var string1:* = XPath.evaluate("/document/element/text()", document); var string2:* = new XPath("/document/element/text()").evaluate(document); trace(string1) // Output: Some Value trace(string2) // Output: Some Other Value var nodeSet:NodeSet = XPath.evaluate("/document/element", document); trace(nodeSet) // Output: <element>Some Value</element>,<element>Some Other Value</element> var boolean:Boolean = XPath.evaluate("1 = 1"); trace(boolean) // Output: true boolean = XPath.evaluate("/document/element/text() = 'Some Other Value'", document); trace(boolean) // Output: false var number:Number = XPath.evaluate("count(/document/element)", document); trace(number) // Output: 2
The snippet below would select a single XML element (the value is returned as the native XML type):
var result1:* = XPath.selectSingleNode("/document/element", document); var result2:* = new XPath("/document/element").selectSingleNode(document); trace(result1) // Output: <element>Some Value</element> trace(result2) // Output: <element>Some Other Value</element>
While the use cases above are simplistic, the XPath library allows for powerful searching of an XML document at runtime. One possible used could be to extend the
DataGridColumn classes to support XPath as a value for the
dataField property, thereby allowing more complex lookups of values.
The AS3 XPath Library is hosted on googlecode. It is built with Maven and consists of two modules.
- as3xpath-core: This is the core functionality and is all that’s required in a project. (API Docs)
- as3xpath-ext-functions: This library contains a small set of functions that can be used in XPath queries, it is not required. (API Docs)
Please report any bugs in the issues section of the googlecode project.
AS3 XPath Library is released under the Apache 2.0 license.
Please offer feedback in the comments, or email me, Andy Lewisohn, at firstname.lastname@example.org.