Wednesday, April 28th, 2010

ActionScript 3 XPath Library

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.

The XPath specification is pretty simple, allowing for the searching (and limiting of those searches) within an XML document that is provided as context. I’m not going to go into how to write XPath, but I’ll point you to the spec for 1.0. I’m a firm believer in not reinventing the wheel, so the first thing I did was look for an XPath library written in ActionScript’s close cousin, JavaScript. It didn’t take much searching to find Form Faces. The project appears to be defunct, but it provided the basis for my implementation. I have optimized the library where possible, but it is still not as fast as the native E4X implementation. The full feature set of the XPath 1.0 specification has been implemented.

One note on how to improve performance: position predicates in the form of /document/element[1] 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[1]/text()", document);
var string2:* = new XPath("/document/element[2]/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[1]/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[1]", document);
var result2:* = new XPath("/document/element[2]").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 DataGrid and DataGridColumn classes to support XPath as a value for the dataField property, thereby allowing more complex lookups of values.

Get it

The AS3 XPath Library is hosted on googlecode. It is built with Maven and consists of two modules.

  1. as3xpath-core: This is the core functionality and is all that’s required in a project. (API Docs)
  2. as3xpath-ext-functions: This library contains a small set of functions that can be used in XPath queries, it is not required. (API Docs)

For those who use Maven to manage dependencies, there is a maven repository here and the source for all releases and current development can be viewed here.

Issues

Please report any bugs in the issues section of the googlecode project.

License

AS3 XPath Library is released under the Apache 2.0 license.

Discuss

Please offer feedback in the comments, or email me, Andy Lewisohn, at andrewl@arc90.com.

Leave a Comment