Code Snippets   | [Bill's Home]

Reading XML from Flash

Macromedia Flash 4 was one of the all-time great software packages. Never before had a package been so easy to use, but yet so powerful. Flash 5, though, saw Flash 4 grown up, and become a well-rounded software development system. For the first time you could actually write action scripts like you write softare programs. Along with with these new scripting techniques came the support for the next big thing on the WWW: XML.

WWW languages of the past, especially HTML, have been fixed in their tags. XML (eXtensible Markup Language) can be used to create new tags, and provide a common platform for transferring information between different systems and packages. The first line of an XML file typically contains an optional xml processing instruction (known as the XML declaration). This can contain pseudo-attributes that indicate the XML language version, the character set, and whether it can be used as a standalone entity. An example is the XML declaration that begins every valid XML file:

<?xml version="1.0" standalone="yes" ?>

The XML document conforms to the XML recommendations, and has a logical structure that is composed of declarations, elements, comments, character references, and process-ing instructions. It also has a physical structure which is composed of entities, starting with the root, or document entity.

XML uses a document type definition (DTD) which defines the rules of the document, such as the elements which are present and the structural relationship between all the ele-ments. It thus defines the tags that can be used and the tags that can contain other tags, the number and sequence of the tags, the attributes of the tags and, optionally, their values. DTDs allow documents to be properly validated, and is used within the production of an XML file. A schema is functionally equivalent to a DTD, but is written in XML. It extends the basic DTD, providing data typing, inheritance, and presentation rules.

The vocabulary of XML is a set of actual elements and the structure for a specific docu-ment type used in particular data formats. These are defined in a DTD that is the rulebook for the vocabulary. One of the first of these languages is the Channel Definition Format which is used to define Web pages that automatically send their contents to users (known as "push" technologies).

The XML object model defines a standard way in which the elements of the XML structured tree are defined. It is fully object-oriented and uses properties, methods, and the actual content (data) contained in an object. This model controls how users interpret the trees, and exposes all tree elements as objects, which can be accessed without any return trips to the server. The XML object model uses the W3C standard know as Document Object Model.

XML-Data Reduced (XDR) is one of the first languages defined which uses a schema (that is one that is defined in an XML form. It defines the:

· Form of elements that are child elements of others.
· Sequence in which the child elements can appear.
· Number of child elements.

It also defines whether an element is empty or can include text. XDR is now well established and uses XML as its basic language. A new standard known as XSD (XML Schema Defini-tion) has been standardized by the W3C XML Schema Working Group.

An XML-based system typically uses an XML engine, which contains an XML parser, an XSL processor, and schema support. The XML parse reads the XML document and provide access to its content and structure. For this it generates a hierarchically structured tree, and passes the data to viewers and other applications for processing. A major function of the XML parser is in checking the XML syntax and report any errors.

XML is similar to HTML, but XML allows for tags to be defined by the user. A good example of an XML file is one which defines questions for a quiz. For example, I've created a simple questions files in XML:

 

<?xml version="1.0" encoding="iso-8859-1"?>
<!DOCTYPE questions SYSTEM "http://www.soc.napier.ac.uk/~bill/flash.xml">
<questions>
 <quest id="000001">
  <title>This is the first question</title>
  <q1>Answer a1</q1>
  <q2>Answer a2</q2>
  <q3>Answer a3</q3>
  <q4>Answer a4</q4> 
  <q5>Answer a5</q5>
  <correct>q1</correct>
  <level>1</level>
 </quest>
 <quest id="000002">
  <title>This is the second question</title>
  <q1>Answer b1</q1>
  <q2>Answer b2</q2>
  <q3>Answer b3</q3>
  <q4>Answer b4</q4>
  <q5>Answer b5</q5>
  <correct>q1</correct>
  <level>2</level>
  </quest>
 <quest id="000003">
  <title>This is the third question</title>
  <q1>Answer c1</q1>
  <q2>Answer c2</q2>
  <q3>Answer c3</q3>
  <q4>Answer c4</q4>
  <q5>Answer c5</q5>
  <correct>q1</correct>
  <level>3</level>
 </quest>
 <quest id="000004">
  <title>This is the forth question</title>
  <q1>Answer d1</q1>
  <q2>Answer d2</q2>
  <q3>Answer d3</q3>
  <q4>Answer d4</q4>
  <q5>Answer d5</q5>
  <correct>q1</correct>
  <level>4</level>
 </quest>
 <quest id="000005">
  <title>This is the fifth question</title>
  <q1>Answer e1</q1>
  <q2>Answer e2</q2>
  <q3>Answer e3</q3>
  <q4>Answer e4</q4>
  <q5>Answer e5</q5>
  <correct>q1</correct>
  <level>5</level>
 </quest>
</questions>

Thus I've defined a <questions> tag, which contains a number of nested questions. Each of these questions has a title (<title>); up to five answers (<q1> to <q6>); a level (<level>) and a correct answer (<connect>). This can be read into Flash 5 with the load action, as given below:

// define the main arrays which will be populated with questions
var question_titles = new Array();
var question_q1 = new Array();
var question_q2 = new Array();
var question_q3 = new Array();
var question_q4 = new Array();
var question_level = new Array();
var question_ans = new Array();
var no_q=0;
urlXML = new XML();
urlXML.onLoad = convertXML;
output1 = "Loading data...";
urlXML.load("questions.xml");
function convertXML () {
 if (this.loaded) {
 output1 = output1 + "<BR>Data loaded.";
}
 mainTag = new XML();
 elementTag = new XML();
 questionList = new Array();
 mainTag = this.firstChild.nextSibling;
 no_q=0; // no of questions in file
 if (mainTag.nodeName.toLowerCase() == "questions") {
// if we have a match, collect all of the questions beneath it as an array of xml objects
 questionList = mainTag.childNodes;
 // get tags
 for (i=0; i<=questionList.length; i++) {
 if (questionList[i].nodeName.toLowerCase() == "quest") {
 // we get the child node array beneath the questions
 elementList = questionList[i].childNodes;
 no_questions=elementList.length;
 // and loop through that looking for the data we need
 for (j=0; j<=elementList.length; j++) {
  elementTag = elementList[j];
  elementType = elementTag.nodeName.toLowerCase();
  if (elementType == "title") {
  question_titles[no_q]=elementTag.firstChild.nodeValue ;
  no_q++;
 }
 if (elementType == "q1") {
  question_q1[no_q-1]=elementTag.firstChild.nodeValue ;
 }
 if (elementType == "q2") {
  question_q2[no_q-1]=elementTag.firstChild.nodeValue ;
 }
 if (elementType == "q3") {
  question_q3[no_q-1]=elementTag.firstChild.nodeValue ;
 }
 if (elementType == "q4") {
  question_q4[no_q-1]=elementTag.firstChild.nodeValue ;
 }
 if (elementType == "correct") {
  question_ans[no_q-1]=elementTag.firstChild.nodeValue ;
 }
 if (elementType == "level") {
  question_level[no_q-1]=elementTag.firstChild.nodeValue ;
 }
}
}
}
}

}

 

 

This will load the XML file locally (such as using it from a CD-ROM or when not connected to the Internet). It is also possible to load the file from a WWW server. For example the load action can be changed to:

urlXML.load("http://billatnapier.com/questions.xml");

For your reference I've included both versions on the ZIP file.

The populated arrays can then be viewed by add the following action to a button:

on (release) {
  output1 = "<BR><B>Question </B>"+(i+1)+" "+question_titles[i];
  output1 = output1+"<BR>"+question_q1[i];
  output1 = output1+"<BR>"+question_q2[i];
  output1 = output1+"<BR>"+question_q3[i];
  output1 = output1+"<BR>"+question_q4[i];
  output1 = output1+"<BR>"+question_q5[i];
  if (i==no_q-1) { stop(); i=0; }
  else {i++; }
}

 

This gives the following output:

One of the great advantages of Flash is that it is component-based, where small media units can be easily integrated with other units to give the full system. We have thus created a general-purpose Flash component, which could be used in our related media content, which can be easily modified to add new questions. The component that we've created is very simple (it took just a few minutes to make), but could be considerably enhanced.