Saturday, August 29, 2009

Creating a Online Book, using EXCEL, XML and Flash

In preparation for the BYOL eLearning Conference, I wanted to create a series of blog postings that highlighted some of the things I will talk about in my presentation on creating simulations and quizzes in Flash using XML.

See conference information here.
http://elearning.byol.com/

Traditionally, if you were to make a simulation that you didn't need to reuse, you would hard code it Flash using the timeline or MovieClips. The problem with creating a simulation this way is that if you want to reuse your code you will have to create the whole simulation over again, and to make changes to your simulation would require a lot of work. The problem I find with Quizzes is that there are a lot of tools out there that help you build quizzes but don't let you customize the look and feel to your liking.
So, basically this is trying to recreate what they have already created. There are pros and cons to creating a custom simulation or quiz but it is sure fun to do.

I first wanted to show how easy it is to use Excel 2007 to create XML documents.
Excel works great for populating a XML document because it feels like you are editing a spreadsheet or a database, you can copy and paste items and you don't have to create start and end tags for each time that you put in some text.

There are some downsides to using Excel as you can only create one level instead of having XML nodes nested inside of other XML nodes. They call this a recursive structure, which works great for creating a Menu, but Excel has trouble doing that kind of structure. There are ways around that though.

In this example, you will learn how to create an simple online book, using Flash, Excel and XML.

First we need to create our XML structure.

Open a code editor such as Dreamweaver and paste in the following code.


<?xml version="1.0" encoding="UTF-8"?>
<Book>
<Title></Title>
<Pages>
<Page>
<Text></Text>
</Page>
<Page>
<Text></Text>
</Page>
</Pages>
</Book>

For sake of simplicity we are just going to create a title for the book and pages using XML.To make sure that Excel knows that there will be more than one page we have to put at least two into our structure.
Save your XML Document.
Open Excel 2007.
Note: You can do this with Excel 2003 but the process is a little different.
To use the XML in Excel you need to have the Developer ribbon enabled.
To do this, click on the Microsoft Office Icon in the top left corner.
Select Excel Options
In the popular tab make sure that Show Developer tab in Ribbon is selected.
Click OK.
Next, click Open from the main menu.
Open the xml file that you saved previously.
When the Open XML pop-up appears select the third option "Use the XML Source task pane. "











An XML Source box should open in the right side of the window.Drag the Title node to the B column.A little box should pop up next to it, click on the option to place the title to the left.This node is a non-repeating element. Next, drag the Page element to the D column. You will notice that this only shows the Text Node, this is because this is the only one that is editable in the Page. We could add other tags such as a page number or chapter number, but Text is enough for right now.

After you have finished mapping the cells. Fill in the spreadsheet. I chose the Count of Monte Cristo because it is in the public domain and can be found at the Gutenberg Project.http://www.gutenberg.org

















Save the file.
Click inside a mapped cell.
Select the Developer ribbon and click Export.
Save the XML file to the same folder where you will create your Flash File.
After you have saved the .xml file go ahead and open it.
You should have something similar to what is found below.


<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Book xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<Title>THE COUNT OF MONTE CRISTO</Title>
<Pages>
<Page>
<Text>On the 24th of February, 1815, the look-out at Notre-Dame de la Garde signalled the three-master, the Pharaon from Smyrna, Trieste, and Naples.</Text>
</Page>
<Page>
<Text>As usual, a pilot put off immediately, and rounding the Chateau d'If, got on board the vessel between Cape Morgion and Rion island.</Text>
</Page>
<Page>
<Text>Immediately, and according to custom, the ramparts of Fort Saint-Jean were covered with spectators; it is always an event at Marseilles for a ship to come into port, especially when this ship, like the Pharaon, has been built, rigged, and laden at the old Phocee docks, and belongs to an owner of the city.</Text>
</Page>
</Pages>
</Book>

It would have taken more time to type out all of the XML tags if we hadn't used Excel.However, you are somewhat limited to what you can do with Excel and XML(i.e. recursive structures) , so I would recommend using Excel only when you have to collaborate with someone else, or you know that you will have a large Excel document.
Create a Flash File using Actionscript 3.0.It should have a dynamic text box for your page text, another dynamic text box for your page numbers and then a back and next button.Your final example could look something like this.


















First, we need to load in the XML.

      var bookXML:XML;

      var xmlLoader:URLLoader = new URLLoader();

      xmlLoader.addEventListener(Event.COMPLETE, xmlLoaded);

      xmlLoader.load(new URLRequest("Count.xml"));

      function xmlLoaded(e:Event):void {

      bookXML = new XML(e.target.data);

      trace(bookXML);

      }


We need to now load the text for each of the pages.We will do this by creating a function that will load the page text and page number text.We will create a load page function that will ask for the current page number.


      function xmlLoaded(e:Event):void {

      bookXML = new XML(e.target.data);

      trace(bookXML);

      loadPage(0);

      }

      function loadPage(pNum:int):void {

      page_txt.text = bookXML.Pages.Page[pNum].Text;

      }

When you reference an XML structure the Root node or our case becomes bookXML. That is why we start with Pages. Each dot (".") represents another level in the XML. This could also be written, bookXML..Page[pNum].Text. Using the two dots allows you to reference all of the Page tags. Test your project to make sure that your text appears correctly.
Next, we need to create a way to go forward and backward through each page.We will do this by creating a currentPage variable and a totalPages variable to help us know where we are in the book.
Place the following variables before the xmlLoaded functions.


      var currentPage:int = 0;

      var totalPages:int;

      function xmlLoaded(e:Event):void {

      bookXML = new XML(e.target.data);

      totalPages = bookXML..Page.length();

      trace(totalPages);

      loadPage(currentPage);

      next_btn.addEventListener(MouseEvent.CLICK, nextPage);

      back_btn.addEventListener(MouseEvent.CLICK, backPage);

      }


Instead of loading Page 0, which is the first page.We will reference the current pages variable.We use the .. Syntax to reference all the pages in the XML.Remember that with XML you must use length() with parenthesis, and not .length.As you use with Arrays.Next we added event listeners to the next and back buttons.

    Next, we will modify the loadPage function.

      function loadPage(pNum:int):void {

      page_txt.text = bookXML.Pages.Page[pNum].Text;

      currentPage = pNum;

      pageNum_txt.text = (currentPage+1) + " / " + totalPages

      }


Whenever there is a change in the page number we will update the currentPage variable. Also, we will send the page number text to the Page Number text box.Remember, that XML starts with Zero so every time that is why we have to add 1 to the currentPage variable.

    Next, we will create our nextPage and backPage button functions.


      function nextPage(e:MouseEvent):void {

      if(currentPage <>

      currentPage++

      loadPage(currentPage);

      }

      }

      function backPage(e:MouseEvent):void {

      if(currentPage > 0){

      currentPage--

      loadPage(currentPage);

      }

      }


On the nextPage function, we have to decrease the totalPages by 1 because it starts counting at 1 where XML starts counting at 0.We do this here so that we don't have to change it in the PageNumber text.However, you could choose where you want to do this.Just be aware that errors will popup if you don't have the correct number.

    Here is the finished script.


      var bookXML:XML;

      var xmlLoader:URLLoader = new URLLoader();

      xmlLoader.addEventListener(Event.COMPLETE, xmlLoaded);

      xmlLoader.load(new URLRequest("Count.xml"));


      var currentPage:int = 0;

      var totalPages:int;


      function xmlLoaded(e:Event):void {

      bookXML = new XML(e.target.data);

      trace(bookXML);

      totalPages = bookXML..Page.length();

      trace(totalPages);

      loadPage(currentPage);

      next_btn.addEventListener(MouseEvent.CLICK, nextPage);

      back_btn.addEventListener(MouseEvent.CLICK, backPage);

      }

      function loadPage(pNum:int):void {

      page_txt.text = bookXML.Pages.Page[pNum].Text;

      currentPage = pNum;

      pageNum_txt.text = (currentPage+1) + " / " + totalPages

      }

      function nextPage(e:MouseEvent):void {

      if(currentPage <>

      currentPage++

      loadPage(currentPage);

      }

      }

      function backPage(e:MouseEvent):void {

      if(currentPage > 0){

      currentPage--

      loadPage(currentPage);

      }

      }


In the next tutorial, I will show how to create a Quiz using EXCEL, XML and Flash, which will build on the concepts learned in this tutorial.