Recipe 19.15 Searching XML

19.15.1 Problem

You want to search an XML object for nodes based on keywords and other criteria such as node hierarchy.

19.15.2 Solution

Use the third-party XPath class from XFactorStudio.com.

19.15.3 Discussion

Thus far in this chapter you've read recipes on how to work with XML objects using the DOM, or Document Object Model. This means that if you want to locate a particular node in the XML tree, you need to know the relationship of that node to the whole (i.e., first child, next sibling, etc.). However, when you want a more flexible way of looking for nodes, the DOM can become tedious.

XPath is a language that allows you a much more intuitive and flexible way to find nodes within an XML object. XPath is a W3C standard (see http://www.w3c.org/TR/xpath) that is supported on many platforms, but it is not natively supported in Flash. However, Neeld Tanksley of XFactorStudio.com has created an ActionScript XPath class that you can download from http://www.xfactorstudio.com/projects/XPath/index.php. You should download the .zip file and extract all the .as files into your Flash Include directory (make sure they are extracted into the Include directory, and not into subdirectories).

Once you have downloaded and installed the custom XPath class, you can include it in your Flash movies and begin using XPath to work with XML, as follows:

#include "XPath.as"

XPath uses path expressions to denote the node or nodes you want to find. For example, if the root node in your XML object is named books, then you can find that root node using:

/books

If books contains child nodes named book, then you can return all the book nodes using:

/books/book

If you don't know or care about the full path from the root node to the node or nodes for which you are searching, you can use a double slash to indicate that you want to locate all matching nodes at any level in the XML tree. For example, the following returns all author nodes regardless of their hierarchy:

//author

An asterisk (*) is a wildcard. For example, the following matches all author nodes that are children of any nodes that are, in turn, children of the books node:

/books/*/author

You can also use square brackets ([]) to indicate criteria that the nodes must match. For example, you can match all book nodes that contain author nodes with the following:

//book[author]

Notice that the preceding is different from //book/author in that the former returns book nodes and the latter returns author nodes.

You can also use expressions with equality operators such as the following, which returns all book nodes containing a child title node with a text value of "ActionScript Cookbook":

//book[title='ActionScript Cookbook']

The @ sign can be used to signify an attribute. The following example matches all author nodes containing a name attribute:

//author[@name]

There are also many other built-in functions, operators, and keywords in XPath that you can read about in the documentation.

The XPath class has one method that we are interested in for this recipe. The XPath.selectNodes( ) method is a static method, which means you invoke it from the class itself, not from an instance of XPath. The method takes two parameters?the XMLNode object to search and the XPath expression to use?and returns an array of matching nodes:

 matches = XPath.selectNodes(my_xml, "/books/book");

Now let's take a look at an example of XPath in use. For this example you should make sure that you have installed all the .as files for the XPath class.

  1. Create an XML document using a simple text editor such as WordPad. Add the following XML code to the document, and then save it as books.xml:

    <books>
      <book>
        <title>ActionScript Cookbook</title>
        <authors>
          <author name="Joey Lott" />
        </authors>
      </book>
      <book>
        <title>Flash Cookbook</title>
        <authors>
          <author name="Joey Lott" />
          <author name="Jeffrey Bardzell" />
        </authors>
      </book>
      <book>
        <title>Flash Remoting: The Definitive Guide</title>
        <authors>
          <author name="Tom Muck" />
        </authors>
      </book>
      <book>
        <title>ActionScript for Flash MX: The Definitive Guide</title>
        <authors>
          <author name="Colin Moock" />
        </authors>
      </book>
    </books>
  2. Open a new Flash document. Copy the PushButton component symbol into the Library by dragging an instance from the Components panel onto the Stage and then deleting the instance. The symbol remains in the Library. Then add the following code to the first frame of the main timeline:

    #include "XPath.as"
    
    function doSearch (  ) {
      // Use the selectNodes(  ) method to find all matches to the XPath expression the
      // user has entered into xpath_txt. Display the results in output_txt. Use a
      // newline character between each match.
      var results = XPath.selectNodes(my_xml, xpath_txt.text);
      output_txt.text = results.join("\n");
    }
    
    // Create the input text field for the user to enter the XPath expression.
    this.createTextField("xpath_txt", 1, 20, 20, 300, 20);
    xpath_txt.border = true;
    xpath_txt.type = "input";
    
    // Create the text field for the output of the results.
    this.createTextField("output_txt", 2, 20, 70, 300, 300);
    output_txt.border = true;
    output_txt.multiline = true;
    output_txt.wordWrap = true;
    
    // Add the push button instance so the user can perform the search.
    this.attachMovie("FPushButtonSymbol", "search_pb", 3, {_x: 20, _y: 45});
    search_pb.setClickHandler("doSearch");
    search_pb.setLabel("Find Matches");
    
    // Set the ignoreWhite property to true for all XML objects.
    XML.prototype.ignoreWhite = true;
    
    // Create an XML object and load books.xml into it.
    my_xml = new XML(  );
    my_xml.load("books.xml");
  3. Save the Flash document to the same directory as the books.xml file. Test the movie. Try entering the following XPath expressions, and you should get the results as shown:

    //book/title

    <title>ActionScript Cookbook</title>

    <title>Flash Cookbook</title>

    <title>Flash Remoting: The Definitive Guide</title>

    <title>ActionScript for Flash MX: The Definitive Guide</title>

    //book[contains(title, `ActionScript')]/title

    <title>ActionScript Cookbook</title>

    <title>ActionScript for Flash MX: The Definitive Guide</title>

    //book[authors[author[@name='Joey Lott']]]/title

    <title>ActionScript Cookbook</title>

    <title>Flash Cookbook</title>

19.15.4 See Also

XPath is too large a subject to cover in detail in this book. For more information, refer to the online tutorial at http://www.w3schools.com/xpath/default.asp or check out the book XPath and XPointer by John E. Simpson (O'Reilly).



    Part I: Local Recipes
    Part II: Remote Recipes