Searching Through XML Objects

It’s not exactly XPath, but it’s handy. The ActionScript 2.0 SearchableXML object below will help find elements in an XML object quickly. Assume, for instance, that you have an XML file like this:


<software>
<tools>
<product name="Flash" version="MX 2004"/>
<product name="Dreamweaver" version="MX 2004"/>
</tools>
<servers>
<product name="ColdFusion" version="MX 6.1"/>
<product name="Flex" version="1.0"/>
</servers>
<foo>
<bar>
<baz>Have a good weekend</baz>
</bar>
</foo>
</software>

The SearchableXML object will let you do this:


import com.macromedia.xml.SearchableXML;

var myXml:SearchableXML = new SearchabelXML();
myXml.parseXML(xmlFileAbove);

// Returns the Flash and Dreamweaver XML elements.
var allTools:Array = myXml.findElement("software.tools");

// Returns the ColdFusion and Flex XML elements.
var allServers:Array = myXml.findElement("software.servers");

// Returns "Have a good weekend"
var msg:String = myXml.findElement("software.foo.bar.baz")[0].firstChild.nodeValue;

Here's the code:


/**
* Adds some search functionality to the XML object.
*
* @author Christian Cantrell
*/
class com.macromedia.xml.SearchableXML
extends XML
{
/**
* Iterates through the XML object, looking for a specific
* element or set of elements.
*
* @path A dot delimited path to the element you're looking for.
*/
public function findElement(path:String):Array
{
var pathNodes:Array = path.split(".");
var currentChild:XML = this;
var elementArray:Array = new Array();
for (var i = 0; i < pathNodes.length; ++i)
{
var children = currentChild.childNodes;
for (var j = 0; j < children.length; ++j)
{
if (children[j].nodeType == 1 && children[j].nodeName == pathNodes[i])
{
if (i == (pathNodes.length - 1))
{
elementArray.push(children[j]);
}
else
{
currentChild = children[j];
}
}
}
}
return elementArray;
}
}

Disclaimer: Only lightly tested for a project I just started working on. Let me know if you find any bugs.