xpath

Yargh!

I’m currently involved in some very heavy manipulation of XML data in a Flash application. For such purposes, I am compelled to use XPath. It’s a decent enough language. Ok, I lied. It’s good. Saves mounds of time that would otherwise be spent iterating over xml tree structures and searching for elements.

When using XPath in Flash, one has two options. First, Macromedia Adobe has a first party implementation. Apparently it’s not that wonderful and nobody who knows better uses it. Second, there’s the XFactor Studio API. This is what I use. It’s what a lot of people use. It is nice. It has never failed me before.

Until today.

I have a very simple favor to ask of the library. I want to select all of a node’s siblings. Now, granted, I am doing some searching to determine which node’s siblings I need here, but it’s really basic.

The XML doc I’m working with looks something like this:

What I want is all <choice>’s in the same <group> as a <product> with a given <p>. Sound simple enough? Well, it is. The XPath statement to do this might look something like this:

//group[products/p='3']/choice
or
//group/choice[../products/p='3']

Both search paths are equally valid and return the same results when I try them out on other xpath implementations.

The XFactor version returns nothing. I know the lib works, and I know I’m using it correctly since my program continues to function up to this point (and I’m making 4 or 5 selections before this point).

So, I’m mildly peeved here. I’ve tried breaking it up into a pair of sequential queries (first select the appropriate group, then select the choices within that group), but that doesn’t do anything either.

So far, this problem has cost me 2 hours this morning and it doesn’t look to be clearing up any time soon. Sigh.

update

After another hour, I have determined that the XFactor XPath implementation is broken when it comes to searching based on text node values. Chris (coworker) swears up and down that it isn’t broken, so he’s trying to prove me wrong now πŸ˜›

In the mean time, I have implemented an ugly brute-force solution to the problem. So, in stead of:
[as3]
var path:String = "//group/choice[../products/p=’"+pid+"’]";
var list:Array = XPath.selectNodes( configurator.firstChild, path );
[/as3]
I have had to settle for something like this:
[as3]
// grab all products
var path:String = "//group/products";
var pNodes:Array = XPath.selectNodes( configurator.firstChild, path );
var gNode:XMLNode = null;

// iterate over products until we find the one we want, YICK
for( var k = 0; k &amp;lt; pNodes.length; k++ ) {
// look at all <p/> children
var tmp:Array = pNodes[k].childNodes;
for( var j = 0; j &amp;lt; tmp.length; j++ ) {
if( tmp[j].firstChild.nodeValue == pid ) {
// parent.parent πŸ™
gNode = tmp[j].parentNode.parentNode;
break;
}
}
if( gNode != null ) break;
}

// grab the appropriate wad of choices, finally
var list:Array = XPath.selectNodes( gNode, "//choice" );
[/as3]

update

After about 20 minutes of headscratching, Chris seems to have given up as well πŸ™‚

Interestingly enough… the first party api doesn’t do it either:
[as3]
var path:String = "//group/choice[../products/p=’"+pid+"’]";
var list:Array = mx.xpath.XPathAPI.selectNodeList( configurator.firstChild, path );
[/as3]
So… I’m very curious if anybody actually does these kinds of searches in Flash? They’re valid according to the W3C spec and they work in Java… for a language like Flash (which is currently handcuffed to XML as its only reasonable means of communication with the outside world) to have a broken XPath implementation is… not good. Sigh.

One thought on “xpath”

Leave a Reply

Your email address will not be published. Required fields are marked *