Using XPath with Flash

A blog post of mine from yesteryear, but the issue came up recently (and the class is undocumented) so I thought I’d reblog it.

Flash MX 2004 introduced the XPathAPI class which allows you to do simple XPath searches within Flash. This can be very useful for searching XML packets based on node names and attribute values.

In order to use XPath searches within Flash you first need to include the XPathAPI class into your Flash library by including the DataBindingClass if it hasn’t been included already. If you’ve already set up bindings this class may have been included automatically, otherwise you’ll need to select the class from the common libraries by selecting Window > Other Panels > Common Libraries > Classes. From the Classes.fla library panel you can simply drag a copy of the DataBindingClasses component into your current Flash document’s library. Now you can import the class by typing “import mx.xpath.XPathAPI;” or by using the classes fully qualified name when accessing its methods by prefixing the class’ methods with mx.xpath.XPathAPI.”.

The XPath class has two methods; selectNodeList and selectSingleNode. The selectNodeList method returns an array of XML nodes matching the XPath expression, whereas the selectSingleNode returns only the first matching node.

You can see an example of the XPath API in ActionScript below, before you can test the movie you have to make sre that you have a copy of the DataBindingClasses component in your movie’s library by dragging it from Common Libraries > Classes into your current Flash movie’s library.

import mx.xpath.XPathAPI;
var rssfeed_xml:XML = new XML();
rssfeed_xml.ignoreWhite = true;
rssfeed_xml.load("http://www.markme.com/dehaan/index.rdf");
rssfeed_xml.onLoad = function(success:Boolean) {
  if (success) {
    var titlePath:String = "/rdf:RDF/item/title";
    var title_array:Array = XPathAPI.selectNodeList(this.firstChild, titlePath);
    for (var i = 0; i<title_array.length; i++) {
      trace(title_array[i].firstChild.nodeValue);
    }
  } else {
    trace("error loading XML");
  }
};

If you want more info on this class, check out Nate Weiss’ book here.

25 Responses to Using XPath with Flash

  1. Richard T-J says:

    Don’t know if this is of interest…As I didn’t know of the above class’s existance, I’ve been using xFactorStudio’s XPath implementation, and have found it to be quite useful.http://www.xfactorstudio.comdirect link is:http://www.xfactorstudio.com/ActionScript/AS2/XPath/btw, how complete an implementation is the built in (XPathAPI) class?

  2. Richard T-J says:

    Whoops, there is an error in the code sample:It seems that using a less than symbol (<) in your blog causes it to wipe anything else on that line…import mx.xpath.XPathAPI;var rssfeed_xml = new XML();rssfeed_xml.ignoreWhite = true;rssfeed_xml.load(“http://www.markme.com/dehaan/index.rdf“);rssfeed_xml.onLoad = function(success) {if (success) {var titlePath:String = “/rdf:RDF/item/title”;var title_array:Array = mx.xpath.XPathAPI.selectNodeList(this.firstChild, titlePath);var titleCount:Number = title_array.length;for (var i = 0; i < itleCount; i++) {trace(title_array[i].firstChild.nodeValue);}} else {trace(“error loading XML”);}};

  3. jdehaan says:

    Thanks Richard, I updated the code in the entry.Sorry about that.

  4. Igor Costa says:

    Correcting the Richard T-J code, much better this one.import mx.xpath.XPathAPI;var rssfeed_xml = new XML();rssfeed_xml.ignoreWhite = true;rssfeed_xml.load(“http://www.markme.com/dehaan/index.rdf“);rssfeed_xml.onLoad = function(success) {if (success) {var titlePath:String = “/rdf:RDF/item/title”;var title_array:Array = mx.xpath.XPathAPI.selectNodeList(this.firstChild, titlePath);var titleCount:Number = title_array.length;for (var i = 0; i < titleCount; i++) {trace(title_array[i].firstChild.nodeValue);}} else {trace(“error loading XML”);}};

  5. John Dowdell says:

    Thanks, Jen, I didn’t know that was there… good news.But why was it “undocumented”? Was it experimental or intended, and did it pass testing or not? What context would people have to put around those literal commands in order to use them confidently…?tx,jd

  6. brandon says:

    Very cool Jen. That will definitely save some time being able to set/get the root element like that.

  7. Hector says:

    If you have ActionScript Viewer installed, you can browse the XPathAPI class and see the following methods listed, although I’m not sure how many are actually useful (apart from selectNodeList and selectSingleNode):class mx.xpath.XPathAPI {  function XPathAPI () {}  static function getEvalString(node, path) {}  static function selectNodeList(node, path) {}  static function selectSingleNode(node, path) {}  static function setNodeValue(node, path, newValue) {}  static function copyStack(toStk, fromStk) {}  static function evalExpr(expr, node) {}  static function filterNodes(nodeList, stack) {}  static function getAllChildNodesByName(nodeList, name) {}  static function getChildNodeByName(node, nodeName) {}  static function getKeyValues(node, keySpec) {}  static function getPath(node, keySpecs) {}  static function getPathSet(path) {}}

  8. jdehaan says:

    I’ll try to answer earlier queries, although note I’m guessing becuase I wasn’t around during the 2004 release. I’d guess the class was tested due to its inclusion in the components. I’m not sure about the story on documentation though. I will file a bug about this to make sure we all look into it.

  9. mike says:

    important to note that of the above-mentioned methods, these re the only public ones:getEvalString(node:XMLNode, path:String);selectNodeList(node:XMLNode, path:String):Array;selectSingleNode(node:XMLNode, path:String);setNodeValue(node:XMLNode, path:String, newValue:String):Numberthe others will say ”i’m private”

  10. sajid says:

    Hi, Any ideas on how to use XPATH in a CLASS?

  11. gjennings says:

    I’ve got a project that was done in MX2004 and uses XFactor Studio to get the value of attributes in nodes. So far, I’ve had no luck getting XFactor’s XPath API to work in Flash 8. Does anyone know if there’s a way to retreive the value of attributes using the Flash XPath API?

  12. Moca says:

    Ola!It is not quite working as I thought.. maybe someone can share a light. This is my xml:16121314And this is my AS copied straight from here:var rssfeed_xml:XML = new XML();rssfeed_xml.ignoreWhite = true;rssfeed_xml.load(“ref.xml”);rssfeed_xml.onLoad = function(success:Boolean) {if (success) {var titlePath:String = “/refList/category”;var title_array:Array = XPathAPI.selectNodeList(this.firstChild, titlePath);for (var i = 0; i<title_array.length; i++) {trace(title_array[i].firstChild.nodeValue);}} else {trace(“error loading XML”);}};When I publish this, it traces:nullnullWhy?In reality what I was trying to do was to get all documents that matches a catId…could I do something like this:/refList/category/@ID==2?

  13. Moca says:

    Ahhh I got it to work like this, after saving their library:import com.xfactorstudio.xml.xpath.*;var myDoc = new XPathDocument();myDoc.onLoad = function(){//select the first nodevar selected_items = myDoc.selectNodes(“//category[@id=’1′]”);////trace the length of itemstrace(“The length of this XML file is “+selected_items.length)//for(var i:Number=0; i<=selected_items.length-1;i++){trace(selected_items[i]);}}myDoc.load(“refDeskTable.xml”);

  14. Catalin Stan says:

    Hi all,I am wondering if any of you knows how much of xpath is implemented in the XPathAPI of Flash8.For instance, queries like/a/b/c[contains(@someattr,’somestring’)]or/a/b/c[@someattr=’@somestring]/..or/a/b[c[@someattr=’@somestring]]which work in other xpath implementations such as MSXML .NET and which are standardized by w3c, will always return no results.I am writting this after having tested such queries on multiple implementations on the same documents.Thanx a bunch!

  15. George Said says:

    I already use XPath tech in my .net applications and also use Stylus Studio 2006 for accurately composing my XPath expressions. Both and all other tools I use agree on the same standards of the language (XPath). The damn question I always ask is: Why Flash insists on being different and being far away from standards.The tiny bit of XPath that Macromedia applied in Flash is very different than the true XPath. I hope that Adobe make things more cleaner and more proffesional.

  16. mayur.GTL says:

    I am new with Flash8.(i) can any one tell me how much Xpath has been supported in Flash8.(ii) how to use Xpath with ActionScript2.0 (any tutorial / example ) ?(iii) can guide me about its any documentation ?Thanking in advance.

  17. Jen says:

    This answers most of your questions (support in Flash 8, how to use, and documentation):http://download.macromedia.com/pub/documentation/en/flash/fl8/XpathAPI.pdf

  18. xtempy says:

    I want to know that The “setNodeValue” statement how to update attribute?thanks in advanced

  19. komekome says:

    so guys, can you tell me how to retrieve the attribute ? there aren’t any article explaining this at all, could you help me out?for example,var titlePath:String = “/rdf:RDF/item/title@name”;var titlePath:String = “/rdf:RDF/item/title/@name”;var titlePath:String = “/rdf:RDF/item/title[@name]”;I tried all, but I cannot get the title attribute! how can I do this?

  20. Marjorie says:

    Same question here: How to to access attributes? Did anyone find the answer to this?

  21. Dylan says:

    This has been driving me crazy for about a month. I’m not using this for RSS but I needed to extract the node attributes for comparison. It doesn’t appear that there is any XPath syntax that will allow you to retrieve an attribute value directly in one line of code. You can filter the nodes by attribute values (i.e. option[@id=1] ) but you can’t return an attribute value using the public XPathAPI methods.Here is how I was able to get the “id” attribute for all of my nodes. You should be able to just substitute your XPath for mine and change “id” to “name”:// Use selectNodeList() from XPathAPIvar relatedNodes_array = new Array();var relatedNodes_array = XPathAPI.selectNodeList(this.firstChild, “/homes/model/option[@id=1]/related_options”);/* Convert Array of length 1 back to XML and then convert the smaller XML tree into an array to get its unknown length. If you already know the length then there is no need for this extra step */var relatedNodesXML:XML = relatedNodes_array[0];var temp_array = relatedNodesXML.childNodes;for(i=0; i<temp_array.length; i++){trace( relatedNodesXML.childNodes[i].attributes[“id”] ); // prints only the id values (1, 2, 3…)}Hopefully this helps some of you. If anyone finds a better solution please post it here.

  22. yau says:

    i use the example download at xfactorstudio XPath4AS2.zipimagine in the myrss.xml , the item has an attribute call imgat line:25, changing adding nodeValue to its attributesrssData.push({Author:author_array[i].firstChild.nodeValue, Title:title_array[i].firstChild.nodeValue});rssData.push({Author:author_array[i].firstChild.nodeValue, Title:title_array[i].attributes.img});finished!

  23. Sumit Gupta says:

    hi,Marjorie, you can simple add .attributes[“id”] in your selectSingleNode statement to get the attribute :),Macromedia forget to mention attributes Array attach to each XMLnode they coded 🙂

  24. Roger says:

    Hi, I came across your blog and found it really interesting.I have started to use XPath in Flash for a project and I am new to it.Please can you advise me on how to get help with the attached file?Its basically going to be a series of text tooltips that will display on mouse over of a button.My AS is:‘====================================================import com.xfactorstudio.xml.xpath.*;var areasXML : XML;areasXML = new XML();areasXML.ignoreWhite = true;areasXML.onLoad = function(success:Boolean) {area1_path = XPath.selectNodes(areasXML, “/areas/area[name=’Bolton’]”);area2_path = XPath.selectNodes(areasXML, “/areas/area[name=’Blackburn’]”);area3_path = XPath.selectNodes(areasXML, “/areas/area[name=’Manchester’]”);Bolton_Text.text = area1_path;Blackburn_Text.text = area2_path;Manchester_Text.text = area3_path;};areasXML.load(“areas.xml”);‘====================================================Many thanks!