Flash Components      Flash Menu      Flash Gallery      Flash Slideshow      FLV Player      Flash Form      MP3 Player      PhotoFlow      Flash CMS      3D Wall      Flash Scroller

Flash / AS

Silverlight

WPF

ASP.net / PHP

Photoshop

Forums

Blog

About

 


FlashComponents
  Galleries
  Slideshows
  Menus
  Design & Effects
  Audio & Video
  User Interface
  Templates

 

 

 

 


Introduction to XML in Flash
       by senocular

Example: Searching XML
Below is an XML file that contains a few posts from the Best of Kirupa.com forum on KirupaForum.com. These are a bunch of posts (ok, only ten but I didn't feel like adding that many) that no one probably wants to read all at once, especially when they're looking for something in particular. It would be nice to just pull out only the post that relates to whatever it is you are trying to find. For that, a search is required.

Depending on the XML being searched, you will need to decide how you want to approach your search. Either way you look at it, searching XML means going through all elements of that XML (or all that are of interest) and checking its content for whatever is being searched. The XML:

bestofposts.xml

It starts off looking like (the entire file is not shown here):

<bestof url="http://www.kirupaforum.com/forums/forumdisplay.php?f=12">
<post url="http://www.kirupaforum.com/forums/showthread.php?t=43216">
<title>xml menu DONE :)</title>
<author>hga77</author>
<message>
<![CDATA[Happy New Year kirupa....Hope all you ppl had a great year and didnt stick to flash too much
 
Anyways I just managed to finish the xml menu i've been working on...
 
I've attached it here incase any1 needs something like this. Use it as you like. Let me know if you make any additions to it
 
UPDATE(04/2004): you can find v2 for this menu on page 3 post #31
UPDATE(07/2004): you can find v3 for this menu on page 15 post #221]]>
</message>
</post>
.
.
.

Each post following this one maintains the same format. As you can probably tell, we should be able to get along fine just using loops. Two will be needed; one nested within the other. One will loop through each post while the other will loop through each element within each post checking it for a match with whatever was searched. The final result is:

[ search for terms within the bestof xml ]

Download ZIP

 

Preparing the Flash File
The file consists of 2 parts, the display area and the search area. The display area shows the XML (in a text field called results_txt), or at least the XML elements that were found in any given search. The search area shows the search input field, some options and the go button.

Because the XML is external and because it has to be loaded to be searched, the search area is self-contained within a movie clip and hidden from view until the loading of the XML is complete. This prevents errors that might have occurred if someone were to search for something in XML that just isn't there.

[ search_fields movie clip symbol ]

When the go button is pressed, the value of the find text field (query_txt) will be sent to a function which will find that value in the loaded XML within any of the elements whose checkbox is selected. Note that each checkbox above says title because their names are dynamically created at runtime (each of the three are the same symbol, each relating to a different element as specified in code).

ActionScript
There are a couple of processes working together to complete the search provided within this example. You have a function to determine what is being searched (where). There's the actual search operation. There's a function used to put the nodes found to have the query in the text field, and then there's a function used to highlight those results in the text displayed.

There's also a custom scrollbar for the search results. I won't go into detail about the scrollbar here, the graphics nor the scripting. It's just like any other custom scrollbar used to scroll content. If you're interested in how its made, you can study the code from the Flash source file. Here, the concentration will be on working with the XML aspects of the example. It will pop up in some other examples as well.

As usual, we'll start with the XML instance used for this example since everything starts with and revolves around its existence.

var posts_xml = new XML();
posts_xml.ignoreWhite = true;
posts_xml.onLoad = function(success){
if (success){
search_fields._visible = true;
}else results_txt.text = "Error loading XML";
}
search_fields._visible = false;
posts_xml.load("bestofposts.xml");

The posts_xml variable here represents the XML instance. It immediately loads the external file "bestofposts.xml" right after the search_fields movie clip has its _visible set to false. Once the loads, in the onLoad event, assuming the loading was successful, search_fields is made visible again and the user can begin to search the data. Otherwise, an error is given in the results_txt text field and you're basically out of luck.

With search_fields visible, the search function is active. This is initiated by the go button on the right. The go button contains the list of commands (functions) that were mentioned earlier. When pressed and released, it:

  • checks for a valid search query (the example limits searches to terms at least 3 characters in length).
  • determines which parts of the XML is to be searched (as specified with the checkboxes).
  • performs the search in the XML with the query provided.
  • displays the results in the results text field.
  • highlights the search term within the results.

That results in the following for the button's onRelease event:

search_fields.search_btn.onRelease = function(){
if (search_fields.query_txt.text.length < 3){
results_txt.text = "Please use a search term with 3 or more characters.";
return (0);
}
 
var searchElements = ElementsToSearch();
 
var nodesWithQuery = SearchXML(
posts_xml.firstChild.childNodes,
search_fields.query_txt.text,
searchElements
);
 
if (nodesWithQuery.length){
DisplayNodes(
nodesWithQuery,
results_txt
);
}else{
results_txt.text = "No results for "+search_fields.query_txt.text+".";
return (0);
}
 
HighlightOccurences(
search_fields.query_txt.text,
results_txt,
search_highlight
);
}

First the check for the valid search query. Since we're only checking for queries with lengths of 3 or greater, this is handled with a simple if condition.

if (search_fields.query_txt.text.length < 3){
results_txt.text = "Please use a search term with 3 or more characters.";
return (0);
}

If the search query (search_fields.query_txt.text) is not at least three characters in length, an error message is displayed and a return statement exits the onRelease preventing anything else from being run.

Next, a function is used to determine which elements within the XML need to be searched.

var searchElements = ElementsToSearch();

ElementsToSearch is defined as:

ElementsToSearch = function(){
var childElementsToSearch = [];
if (search_fields.title_check.checked){
childElementsToSearch.push("title");
}
if (search_fields.author_check.checked){
childElementsToSearch.push("author");
}
if (search_fields.message_check.checked){
childElementsToSearch.push("message");
}
return childElementsToSearch;
}

What this does is is runs through the checkboxes within the search_fields movie clip, adding the associated element node name to an array if the checkbox is checked. This array is then returned and assigned to searchElements to be used within the search function.

The search is what comes next. The function handling the search is called SearchXML. It takes an array of elements to be searched (a childNodes array), what is to be searched and an array of elements within the elements searched... to be searched.

var nodesWithQuery = SearchXML(
posts_xml.firstChild.childNodes,
search_fields.query_txt.text,
searchElements
);

posts_xml.firstChild.childNodes represents the list of post elements within posts_xml. Each of those post elements contains title, author and message elements. Which of those to be searched is dictated by the searchElements array originally obtained by the ElementsToSearch function. As for the SearchXML function, it comprises of the following:

SearchXML = function(nodes, query, useChildElements){
var results = [];
for (var i=0; i<nodes.length; i++){
for (var j=0; j<nodes[i].childNodes.length; j++){
currNode = nodes[i].childNodes[j];
if (useChildElements.contains (currNode.nodeName)){
if (currNode.firstChild.nodeValue.contains (query)){
results.push(nodes[i]);
break;
}
}
}
}
return results;
}

Using 2 for loops, one nested in the other, this takes and places all post elements that contain the query in a returned results variable. The first loop which uses the i variable as an iterator loops through all post elements passed in as the nodes variable (set to posts_xml.firstChild.childNodes when called). The second loop, using j, cycles through all of each of the child nodes within each of those elements; in this case, title, author and message.

[ nested for loops for post elements ]

Inside those loops, as looping through each post element, the useChildElements array (searchElements) is checked to see if that particular node is to be searched by seeing if its nodeName exists within it. If so, the following if statement does the actual searching through that element's text Node for the query. If that exists, then the post element is added to the results array and the inner for loop (j) is broken out of in order to immediately begin searching the next post element. When all post elements are searched, the results array is returned and assigned to the nodesWithQuery variable back in the go button's onRelease event.

You may not recognize the two functions (though with a similar name) used to check the useChildElements array and the text node for the search query. These are the Array and String contains methods. You probably don't recognize them because they're custom methods defined to work with the String and Array objects. They are defined within the movie as:

String.prototype.contains = function(searchString){
return (this.indexOf(searchString) != -1);
}
Array.prototype.contains = function(searchValue){
var i = this.length;
while(i--) if (this[i] == searchValue) return true;
return false;
}

They're simple enough that they could be written directly within the Search XML function, but separating them like this keeps SearchXML cleaner and more understandable. Its much easier to tell what's going on when you read if string contains word versus if string indexof word != -1 when determining when a string (word) exists within another. (If you're unfamiliar with indexof for Strings, it returns the location of one string within another. If the string does not exist within the other string, -1 is returned.)

Getting back to the original go button's onRelease, the next item up for bid is the displaying of the results within the results_txt text field.

if (nodesWithQuery.length){
DisplayNodes(
nodesWithQuery,
results_txt
);
}else{
results_txt.text = "No results for "+search_fields.query_txt.text+".";
return (0);
}

An if statement is needed here because we need to check to see whether or not there are any results to display. If there are, call DisplayNodes to put the nodesWithQuery elements into results_txt. If not, then display an error message there instead. DisplayNodes is defined as:

DisplayNodes = function(nodes, field_txt){
field_txt.htmlText = "";
var entry;
var separator = "<br>_______________________<br><br>";
for (var i=0; i<nodes.length; i++){
entry = "";
entry += "<b>"+ nodes[i].childNodes[0].firstChild.nodeValue +"</b>";
entry += " by: "+ nodes[i].childNodes[1].firstChild.nodeValue;
entry += "<br>"+ nodes[i].childNodes[2].firstChild.nodeValue;
if (nodes[i].attributes.url.length){
entry += "<br><a href='" + nodes[i].attributes.url;
entry += "'><font color='#0000FF'>Read more...</font></a>";
}
field_txt.htmlText += entry + separator;
}
}

DisplayNodes simply formats the XML to be displayed in the text field (using HTML).

At this point the search is complete. All nodes with the query have been found and displayed in the results_txt. To make the results a little more convenient, though, I've added a little function that goes through and highlights the search terms within the results. This is the HighlightOccurences function.

HighlightOccurences(
search_fields.query_txt.text,
results_txt,
search_highlight
);

It's defined as:

search_highlight = new TextFormat();
search_highlight.color = 0xFF0000;
search_highlight.italic = true;
 
HighlightOccurences = function(str, field_txt, format){
if (!str.length) return (0);
var start = field_txt.text.indexOf(str);
var end = start + str.length;
while (start != -1){
field_txt.setTextFormat(start, end, search_highlight);
start = field_txt.text.indexOf(str, end);
end = start + str.length;
}
}

It uses a TextFormat instance to make all the str (query) instances within the field_txt text field (results_txt) turn red - or at least whatever the format passed specifies. And that format you can see defined above the function does in fact set text red.

 


 


kirupa.com's fast and reliable hosting provided by Media Temple. flash components
The Text Animation Component for Flash CS3
Check out the great, high-quality flash extensions. Buy or sell stock flash, video, audio and fonts for as little as 50 cents at FlashDen.
Check out our high quality vector-based design packs! Flash Effect Components
flash menus, buttons and components Digicrafts Components
The best flash components ever! Entheos Flash Website Templates
Upload, publish, deliver. Secure hosting for your professional or academic video, presentations & more. Screencast.com Purchase & Download Flash Components
flash components Free Website | Make a Website
Streamsolutions Content Delivery Networks Learn how to advertise on kirupa.com