| Using
XML with Flash (Part 2)
|
 |
 |
Introduction
This
is an update to the original
latest news tutorial. The original
tutorial still provides a good introduction
to flash and XML. However there where a
few things that are pretty lacking with
the original version:
- The XML file is in a custom format
- Everything is parsed into an array
- The parsing is tied to a specific
XML structure
- It is not very expandable
- There was code everywhere
Resources: Flash
.fla file (Flash MX, zipped), Flash
.swf file (Flash Player 6), XML
file. |
 |
Contents
|

|
 |
 |
|
Using
the defined RSS XML news feed standard
|
 |
When
building a site and deciding to go to
the effort of using XML there is no point
in creating your own standards for your
XML documents when defined standards
exist. The XML used for the original
latest news tutorial is a classic example
of creating your own standards. If I
wanted to expand the use of the flash
program or use the XML in other programs
I would have to write all the code. However
thousands of other people are already
sharing headlines and titles of news
and blog articles. If you use a XML standard
then it is a simple matter of dropping
in other peoples code to manipulate your
XML feed. In the case of XML news feeds
there is a definite standard, RSS. I
won't go into the whys and hows of RSS,
however there is an excellent article
providing and introduction at xml.com
These days RSS feeds are everywhere with
most news sites providing an RSS feed and
other sites aggregating the feeds. Where
and how you get your RSS feed is up to
you, however it does have to be accessible
from your website. Flash security will
not allow you to go out onto the internet
and get someone elses feed, if you want
to grab someone elses feed check out the Flash-XML
FAQ section on security.
For the purposes of this tutorial I am
going to use a static XML file.
Here is what a basic rss XML file looks
like:
<rss
version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/">
<channel>
<title>Flash @ Tupps</title>
<link>http://www.tupps.com/flash</link>
<description>Flash @ Tupps is a unique source of
original information about using XML in Macromedia Flash 5, MX and MX 2004</description>
<language>en-us</language>
<item>
<title>Scrolling Text Box</title>
<link>http://www.tupps.com/flash/examples/scrolling_text/demoText.html</link> <description>This
is an example text box that slowly scrolls the content received from an XML file.
The user can access the scroll box at any time and move it up and down.</description>
<dc:creator>Luke Tupper</dc:creator>
<dc:date>2003-05-23</dc:date>
</item>
<item>
<title>Displaying a plain
text break from a xml file.</title> <link>http://www.tupps.com/flash/examples/plain_break/demoText.html</link>
<description>This example
allows the user to use a plain text breaks in the xml file and display the text
correctly in a flash text box.</description>
<dc:creator>Luke Tupper</dc:creator>
<dc:date>2003-04-11</dc:date>
</item>
<item>
<title>Displaying html
breaks from a xml file.</title> <link>http://www.tupps.com/flash/examples/html_break/demoText.html</link>
<description>This example
allows the user to use a html text in the xml file and display the text correctly
in a flash text box.</description>
<dc:creator>Luke Tupper</dc:creator>
<dc:date>2002-04-09</dc:date>
</item>
</channel>
</rss>
For
the latestnews the only items we are interested
in are the individual items, and for each
item the title and the link.
Another advantage of this latest news display
is that it is not difficult to modify it
to be a full blown rss news reader. It
has been designed so that nearly all of
the code written can be reused in another
player (feel free to take the code). |
 |
|
|
 |
 |
|
Reducing
the amount of code by parsing into
an array
|
 |
This
version of the latest news has reduced
the number of places that code exists.
All of the XML handling code and the
code to fade in and out the title is
on frame 1 of the layer named 'actions'.
The only other code in the flash movie
is a clip event on the movie containing
the text node that causes the link to
fired off when a user clicks on the title.
The first time we parse the xml file we
want to find all the item nodes and for
each one a title and a link. In the original
latest news tutorial I created two arrays
to store this information. A better way
to do this is to store an array of objects
with each object referencing the original
node in XML data. This will allow any expansion
of our code to handled easily because you
will be able to get to the original XML
data without having to create another array
of data. The other advantage is that we
can add methods to the objects to extract
the information that we require. Before
we jump to parsing the data there are a
couple of things we have to be aware of.
The most important is that there might
be multiple channel tags in the RSS feed.
To deal with this we will search the entire
XML tree for 'item' nodes, therefore making
sure we don't miss anything if the document
is rearranged. This will also make our
application more robust if the XML changes,
and more likely to be backward compatible
with older formats of RSS. |
 |
|
|
 |
 |
|
Calling
the extractData function
|
 |
First
we need to load the XML. The first step
is to create the XML object (line 8)
When the XML is loaded and parsed we
want flash to call the extractData function,
this is assigned on line 9. Flash implements
this as a call back, so if you are tracing
through this code you will find that
extractData is called after the rest
of the code on frame 1 has been run.
Finally we tell the xml object to load
ourXML file (line 10). If the XML file
is in a different directory you will
have to specify an exact path (eg. /newsfeed/rss.xml)
or as a relative path (eg. ../../rss.xml).
//Load the XML
rssXML = new XML();rssXML.onLoad = extractData;rssXML.load("rss20.xml");
//Link to the rss20.xml file in the same
directory as the flash file.
(lines 7-10)
The extractData function is responsible
for making sure that the XML has been loaded
correctly (line 17). If everything is loaded
and parsed correctly by the flash player
then we call the parseTree function (line
22). The parseTree function will 'walk'
through all of the nodes in the XML looking
for item nodes.
When
parseTree has finished the itemsArray should
be populated with an array of items from
the XML file. I have left a trace statement
here that I used in my original testing
to make sure everything was working correctly.
I always use the philosophy if you have
put in trace statement to get some critical
information for debugging then you might
as well leave it in so that the next time
you want that information it will be there
ready for you. Plus having tons of scrolling
text on your screen always makes it seem
as though you know what you are doing ;-) |
 |
|
|
 |
 |
|
The
showText routine
|
 |
If
you would like to look at the other code
used in Latest News the code is contained
in two areas:
On the Text layer, frame 3, the XML is
checked that it is loaded, then a random
news item is chosen. The user clicks on
a movie called invisibleButton which is
a located on the HitButton layer, and opens
a new web page with the URL.
The final call is to the showText routine.
This routine (which I don't outline in
this tutorial) is responsible for making
the text display and disappear at various
points. Also the first time the routine
is run and every time the text fades out
it will choose a new random text string
to display (see getNewText function line
113).
If the extractData function cannot load
or process the XML file it should have
a better warning than simply outputting
a trace statement. I will leave that up
to you to do.
//This
function gets called when the XML has fully
loaded
function extractData(success)
{
//Success will be true if flash could open and parse
all the XML content.
if (success) //Line 17
{
//Within the function in the
callback from the XML onLoad statement
//the variable 'this' refers
to the XML document that has been
//successfully loaded by XML
function.
parseTree(this);//Line 22
trace("Array Length: " +
itemsArray.length); //How many records did we find?
//Now start the latest news rolling:
showText();
}
else
{
//Should have a failure handler
here!
trace("XML Load Failed");
}
trace("Finised Extracting");
}
(Lines 13-38) |
 |
|
|
 |
 |
|
The
parseTree function
|
 |
The
parseTree function is a recursive function
call, a node is passed to the parseTree
function, if that node contains other
nodes then each of those childNodes
are checked by a new instance of the
parsTree function to see if they are
an item node. The for loop is used
to go through each child node one at
a time. I have left the trace statement
in so it is easy to check that the
system is parsing the entire XML file.
If we encounter an item node we will
call the extractItem function. If we
encounter anything else we will call
the parseTree function again.
If you haven't programmed with recursive
functions call this can be a bit of mind
bender and can be tricky to debug. However
this method of parsing XML files is great
if you are not in control of the format
of the XML file. Flash can make up to
256 recursive calls before its call stack
(the thing to keep track of which functions
have called other functions) is full.
In a practical sense this means that
we can parse a XML file that is up to
250 or so nodes deep (eg firstNode.firstNode.firstNode
would be 3 nodes deep), I doubt there
are many XML files out there that have
a node heirachy greater than 250 nodes
deep. Note: this is not how many nodes
and XML file has but how many parents
a node has. Most XML files are 2-6 nodes
deep and complicated XML files might
have a hierachy with more than 10 nodes.
250 nodes seems would be an extremely
complicated XML file.
function parseTree(xmlNode)
{
//Go through each node, if it
is an item node then add items to the itemsArray
//Else go through each of the
child nodes and recursively call this function
//foreach child node. Note item
nodes inside other item nodes will not be found.
trace("Parsing this: " +
xmlNode.toString()); //Used for initial debugging to make sure xml parsing is
working.
if (xmlNode.hasChildNodes())
{
//Something
funny in the parsing here.
for (var
i = 0; i < xmlNode.childNodes.length; i++)
{
trace("xmlNode.childNodes[" +
i + "].nodeName: " +xmlNode.childNodes[i].nodeName);
if
(xmlNode.childNodes[i].nodeName == "item")
{
//Extract
the RSS item
extractItem(xmlNode.childNodes[i]);
}
else
{
//Call
parseTree to scavenge through this nodes childNodes
parseTree(xmlNode.childNodes[i]);
}
}
}
}
(lines 37-63)
|
|
|
 |
 |
|
The
extractItem function
|
 |
The
final part of our program for dealing
with the XML file is the extractItem
function. This routine is fairly simple
because most of the actually data handling
is done in our newsItem object (lines
173-200). The object is initialised with
the XML node (line 77). If the user requests
a title or the link function this will
call a routine that searches and extracts
the relevant details. If both of the
title and link exist (if they don't our
program would not display any information,
or you couldn't go to the article) we
will add the new object to our array
of news items.
function
extractItem(xmlNode)
{
//This function adds an item
to the array of items that will be used for
//latest news.
//We need to find two items,
the title, and the link url. If either of them
//are not found then we needn't
bother adding this item to the array.
var title = null;
var link = null;
if (xmlNode.hasChildNodes())
{
var newsItem
= new newsItem(xmlNode);
trace("Title: " +
newsItem.title() + " Link: " + newsItem.link());
if (newsItem.title()
!= null && newsItem.link() != null) //check to make sure the title and
link have been set.
{
//Assign
it into the array.
itemsArray.push(newsItem);
}
}
}
(lines 65-86)
The newsItem object is the one that is
responsible for doing the last steps in
the XML extraction. In our case the object
has 1 property and 2 functions. The property
is the xmlNode. This contains the item
xml data. The two functions get the title
and the link for us. The function calls
getTitle and getLink are called and they
in tern call the findNode function, passing
the appriorate name to be retreived. If
you wanted to expand this application to
receive other information (descriptions,
author name, etc) then you would start
by adding additional functions similar
to getTitle and getLink, then add them
to the newsItem object.
//Class constructor
function newsItem(xmlNode)
{
this.xmlNode
= xmlNode;
this.title
= getTitle;
this.link
= getLink;
}
function getTitle()
{
return
findNode(this.xmlNode, "title");
}
function getLink()
{
return
findNode(this.xmlNode, "link");
}
function findNode(xmlNode, nodeName)
{
for
(var i = 0 ; i < xmlNode.childNodes.length; i++)
{
if
(xmlNode.childNodes[i].nodeName == nodeName)
{
return
xmlNode.childNodes[i].firstChild.nodeValue;
}
}
}
(Lines 173-200)
In approximately 100 lines of code including
comments and whitespace we have extracted
our XML files and are ready to display
them. Three additional routines showText,
hideText and getNewText exist to handle
the fading in and out of the text. This
is done using a timer that is continously
set by these routines to call themselves
in a short period of time. Be aware that
if you use these routine and are trying
to fade text in and out that you must embed
the outlines of the text, otherwise the
text won't allow color transformation effects
to be applied (I can tell you that was
a fun thing to nut out!). |
 |
|
|
 |
 |
| This
tutorial was written by Luke
Tupper who runs Tupps.com. |
 |