1. Trang chủ
  2. » Công Nghệ Thông Tin

Học Actionscript 3.0 - p 43 doc

10 227 0

Đang tải... (xem toàn văn)

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Định dạng
Số trang 10
Dung lượng 4,92 MB

Nội dung

Writing XML Chapter 14: XML 399 Writing XML You’ve already seen how to write XML when creating an instance of the XML class, but you may also have to write to the instance over time. For example, you may need to add to XML based on user input or as data changes. The majority of techniques for adding content to XML mirror the process of read- ing the data, except this time you’re assigning information to a node rather than retrieving it. In this section, you’ll re-create the data used throughout the “Reading XML” section of this chapter. For simplicity, we’ll create element nodes, text nodes, and attributes in one example, and build an XML instance as if we were writ- ing it over time. In a real scenario you would not assemble XML in multiple steps in the same script. However, assuming the premise that we’re writing the object in stages will allow us to demonstrate the most common XML writing methods. Because we’re intentionally writing the XML out of order to demonstrate methods like insertChildBefore() that will alter the order of nodes, we’ll show the progress of the XML as we go. The code that follows can be found in the write_xml.fla source file. For clarity, only the last trace() statement is used in the source file, to show the final XML content, but you can uncom- ment any trace along the way to see interim results. To begin, we must have an XML instance and a root node, so line 1 creates both. Note that, when adding element nodes without content, you must specify a self-closing tag so the XML remains well formed. As soon as you add content to a self-closing node, ActionScript will replace it with balanced open and closing tags. For example, we’re initially adding <book /> as the root node but, after adding the next element node, the root node will become <book> </book> . Line 2 demonstrates the simplest technique for creating both an element node and a text node. When assigning a value to a node, if the node does not already exist, it will be created. If you assign another element node to the new node, a nested element will be created. If you assign a String to the new node, a text node will be created. Line 2, therefore, creates an element node called <title> and a text node that contains “Learning ActionScript 3.0.” The result appears in lines 5 through 7. 1 var las3Data:XML = <book /> 2 las3Data.title = "Learning ActionScript 3.0"; 3 trace(las3Data); 4 /* 5 <book> 6 <title>Learning ActionScript 3.0</title> 7 </book> 8 */ We started with the <title> node intentionally to demonstrate the next method. The prependChild() method will add a node to the beginning of Download from Wow! eBook <www.wowebook.com> Part V: Input/Output 400 Writing XML the XML object specified. In this case, line 9 creates the <publisher> ele- ment node and positions it before the <title> node so it’s the first node of las3Data. Line 10 demonstrates the creation of an attribute node adding the name attribute to the publisher element node just created. The cumulative result appears in lines 13 through 16. 9 las3Data.prependChild(<publisher />); 10 las3Data.publisher.@name = "O'Reilly"; 11 trace(las3Data); 12 /* 13 <book> 14 <publisher name="O'Reilly"/> 15 <title>Learning ActionScript 3.0</title> 16 </book> 17 */ The opposite of prependChild(), appendChild() adds a node to the end of an XML object. Therefore, line 18 adds the <authors> node after the <title> node. Up to this point, we’ve only added objects to the XML instance, which is equivalent to the root node. However, you can also use appendChild() to add a child to another node. Line 19 adds the first <author> node as a child of <authors>. Lines 20 and 21 again demonstrate the simultaneous creation of element and text nodes, adding <firstname> and <lastname> nodes and assign a String to each. The cumulative result appears in lines 24 through 33. 18 las3Data.appendChild(<authors />); 19 las3Data.authors.appendChild(<author />); 20 las3Data.authors.author.firstname = "Zevan"; 21 las3Data.authors.author.lastname = "Rosser"; 22 trace(las3Data); 23 /* 24 <book> 25 <publisher name="O'Reilly"/> 26 <title>Learning ActionScript 3.0</title> 27 <authors> 28 <author> 29 <firstname>Zevan</firstname> 30 <lastname>Rosser</lastname> 31 </author> 32 </authors> 33 </book> 34 */ Line 35 demonstrates the insertChildAfter() method, the first of a pair that allows you to provide an existing node as a reference point for where the new node should be added. The first argument of the method is the existing node, and the second argument is the node you want to create. In this case, the <subject> node is being inserted after the <title> node. Line 36 adds a text node to <subject>, and the cumulative result is seen in lines 39 through 49. 35 las3Data.insertChildAfter(las3Data.title, <subject />); 36 las3Data.subject = "ActionScript"; 37 trace(las3Data); 38 /* 39 <book> 40 <publisher name="O'Reilly"/> N OT E It’s not possible, using this method, to add more than one node with the same name to an XMLList. For example, we have to add another author to the <authors> node, but if we repeat lines 19 through 21, we’ll receive this error: Error #1089: Assignment to lists with more than one item is not supported. Instead, we must copy the first author node and change its contents. We’ll show you how to do that in just a moment. Download from Wow! eBook <www.wowebook.com> Deleting XML Chapter 14: XML 401 41 <title>Learning ActionScript 3.0</title> 42 <subject>ActionScript</subject> 43 <authors> 44 <author> 45 <firstname>Zevan</firstname> 46 <lastname>Rosser</lastname> 47 </author> 48 </authors> 49 </book> 50 */ The next block of code demonstrates insertChildBefore(), the other method that uses an existing node as a reference. However, it also demonstrates how to copy a node and change its values. Line 51 uses the copy() method to copy the previously created <author> node, and lines 52 and 53 change the text nodes in <firstname> and <lastname>. After the edits, the new node is inserted before the existing <author> node to match the order of the original data we’re trying to recreate. Using the copy() method is a real timesaver when tags with many children must be reproduced over and over again with few changes. The final result is shown in lines 57 through 71, and matches the original las3Data object to achieve our goal. 51 var firstAuthor:XMLList = las3Data.authors.author.copy(); 52 firstAuthor[0].firstname = "Rich"; 53 firstAuthor[0].lastname = "Shupe"; 54 las3Data.authors.insertChildBefore(las3Data.authors.author, firstAuthor); 55 trace(las3Data); 56 /* 57 <book> 58 <publisher name="O'Reilly"/> 59 <title>Learning ActionScript 3.0</title> 60 <subject>ActionScript</subject> 61 <authors> 62 <author> 63 <firstname>Rich</firstname> 64 <lastname>Shupe</lastname> 65 </author> 66 <author> 67 <firstname>Zevan</firstname> 68 <lastname>Rosser</lastname> 69 </author> 70 </authors> 71 </book> 72 */ Deleting XML We’ve placed deleting XML elements in a separate section because you may delete elements when reading or writing XML. When parsing XML, you’re likely to ignore small sections of unwanted content, but deleting large seg- ments of unneeded material can sometimes simplify your task. When writing Download from Wow! eBook <www.wowebook.com> Part V: Input/Output 402 Loading External XML Documents XML, you may find the need to delete an element added in error or that is no longer needed. To delete something, simply use the delete operator on the desired item. Here are a few examples showing how to delete attributes, element nodes, and text nodes from a simplified version of our ongoing las3Data example. This code can be seen in the delete_xml.fla source file. Line 7 deletes an attribute, line 8 deletes an element node and all its children (which deletes the text node therein), and line 9 deletes only a text node, leaving the parent element node intact. The final result is seen in lines 12 through 15. 1 var las3Data:XML = <book> 2 <publisher name="O'Reilly" /> 3 <title>Learning ActionScript 3.0</title> 4 <subject>ActionScript</subject> 5 </book>; 6 7 delete las3Data.publisher.@name; 8 delete las3Data.subject; 9 delete las3Data.title.text()[0]; 10 trace(las3Data); 11 /* 12 <book> 13 <publisher/> 14 <title/> 15 </book> 16 */ Note that the delete operator won’t work with text(), elements(), attri- butes() , children(), or descendents() to delete all of the nodes returned by these methods. Rather, you must specify which item within the XMLList returned that you want to delete. This can be counterintuitive if you just want to delete a single text node, as in line 9. Loading External XML Documents Often when you work with XML, you’re using data that’s being retrieved from an external source. Even when you need only a local data source, however, it’s almost always easier to work with an external XML document because it’s easier to edit the XML as you project evolves. We’ll use the LoadURL class developed in Chapter 13 to load data for our XML navigation system at the end of this chapter, but right now we’d like to stress the basic syntax of loading XML. The code in this section can be found in the load_xml.fla source file. Before we get started with the syntax, let’s create a very simple XML docu- ment called toLoad.xml. It contains the mandatory root node, one element node called <stuff>, and one text node with the string, “XML loaded!” <main> <stuff>XML loaded!</stuff> </main> Download from Wow! eBook <www.wowebook.com> Loading External XML Documents Chapter 14: XML 403 With that in hand, let’s start our script by creating a text field to display our results (lines 1 through 5). This is a handy alternative to tracing loaded con- tent because it’s easier to test in a browser. Next, create a URLRequest instance for the XML file (line 7), and a URLLoader instance to load the document (line 9). Then create two event listeners to react to a possible I/O error (lines 10 and 11), and the completion of the loading process (lines 12 and 13). The onIOError() function in lines 16 through 18 places any error text (if an I/O error occurs) into a text field, and we’ll discuss the onComplete() function after the first code block. Next, the XML document is loaded in line 14. 1 var txtFld:TextField = new TextField(); 2 txtFld.width = 500; 3 txtFld.height = 350; 4 txtFld.multiline = txtFld.wordWrap = true; 5 addChild(txtFld); 6 7 var req:URLRequest = new URLRequest("toLoad.xml"); 8 9 var urlLoader:URLLoader = new URLLoader(); 10 urlLoader.addEventListener(IOErrorEvent.IO_ERROR, 11 onIOError, false, 0, true); 12 urlLoader.addEventListener(Event.COMPLETE, 13 onComplete, false, 0, true); 14 urlLoader.load(req); 15 16 function onIOError(evt:IOErrorEvent):void { 17 txtFld.text = "XML load error.\n" + evt.text; 18 } The onComplete() function (lines 19 through 28) is triggered when the XML file has completely loaded. The function first removes the listeners because the XML document was both found and loaded. It then uses a try catch block to create an XML instance from the loaded data, and places the <stuff> node into a text field. If unsuccessful, an error message is placed into the same field, often allowing you to locate something that may cause the XML to be malformed. 19 function onComplete(evt:Event):void { 20 urlLoader.removeEventListener(IOErrorEvent.IO_ERROR, onIOError); 21 urlLoader.removeEventListener(Event.COMPLETE, onComplete); 22 try { 23 var loadedXML:XML = new XML(evt.target.data); 24 txtFld.text = loadedXML.stuff; 25 } catch (err:Error) { 26 txtFld.text = "XML parse error:\n" + err.message; 27 } 28 } Before we demonstrate populating menus with XML in our navigation sys- tem project, let’s look at sending data to a server and loading the result. Download from Wow! eBook <www.wowebook.com> Part V: Input/Output 404 Sending to and Loading from a Server Sending to and Loading from a Server Another frequent use of XML data is for transmission to and from a server. XML is often the data format used by news feeds (RSS, ATOM), Web services, and database output. While some of these uses require only loading informa- tion, other tasks, including application logins, game high score submission, and so on, also require sending data. In this chapter, we’ll cover the basic send and load method of communicating with a server. Send and Load The send-and-load approach is a form of traditional server communication, be it a browser retrieving an HTML file or a user submitting data via a form. Essentially, the client sends data to the server and waits for a response. The server processes the incoming information, formulates a reply, and sends information back to the client. For simplicity, this example sends a short XML object to a PHP script, which then writes data to a text file on the server and sends back a short reply. Writing a text file on the server may not be the most common use of XML submissions, but it’s basic enough to illustrate in this context. This example uses two files: send_load_xml.fla and save_xml.php. Let’s look at the FLA file first. The client source This example is nearly identical to the load_xml.fla source file discussed in the preceding “Loading External XML Documents” section. All we need to do is substitute the following eight lines of code for line 7 of that example. These lines both create XML to send, and customize the URLRequest instance to send data, as well as load it. Lines 7 through 9 create the XML object to send to the server. Like ActionScript, our PHP script does not require the XML declaration tag in line 7 but, for maximum flexibility, it’s not a bad idea to prepend this to any XML you send to a server. You may find that it’s required in a future configuration of your project and, since it makes no difference in ActionScript, there’s no good rea- son not to include it. Lines 11 through 14 create a URLRequest instance for submitting the data. Note that you’ll need to put the correct path to your server in line 11. As discussed in Chapter 13, line 12 assigns the outgoing XML to the data property of the request, and lines 13 and 14 specify “text/xml” as the contentType, and POST as the method, of the request object, respectively. 7 var str:String = "<?xml version='1.0' encoding='utf-8'?>"; 8 str += "<value>Sent from ActionScript</value>"; 9 var xmlToSend:XML = new XML(str); 10 Download from Wow! eBook <www.wowebook.com> An XML-Based Navigation System Chapter 14: XML 405 11 var req:URLRequest = new URLRequest("save_xml.php"); 12 req.data = xmlToSend; 13 req.contentType = "text/xml"; 14 req.method = URLRequestMethod.POST; The server source The next code block is the server-side PHP script. This is the server destina- tion of your simple XML data and, as specified in line 11 of the ActionScript code, should be called save_xml.php. The script first checks to be sure POST data has been received (line 3), and then populates the $data variable with that data (line 4). In lines 6 through 8, it creates and opens for writing a file called data.txt, writes the data to the file, and then closes the open file instance. Lastly, it checks to make sure the file was written successfully and sends a simple XML object back to ActionScript. If successful, you’ll see the message “File saved.” in the text field. If not, you’ll see “Server unable to create file.” There may be a permissions issue on the server preventing write access to the directory in which the PHP script has been placed, for example, or another error preventing file creation. 1 <?php 2 3 if (isset($GLOBALS["HTTP_RAW_POST_DATA"])){ 4 $data = $GLOBALS["HTTP_RAW_POST_DATA"]; 5 6 $file = fopen("data.txt", "wb"); 7 fwrite($file, $data); 8 fclose($file); 9 10 if (!$file) { 11 echo("<stuff>Server unable to create file.</stuff>"); 12 } else { 13 echo("<stuff>File saved.</stuff>"); 14 } 15 } 16 17 ?> An XML-Based Navigation System If you haven’t done so already, you may want to read the last exercise in Chapter 6, before continuing with this project. Chapter 6 discusses object- oriented programming and uses a simplified version of this exercise without XML, populating the menus with an array. By comparing this exercise with the more basic version in Chapter 6, you can see how incorporating XML changes the system. The result of this exercise will be a five-button naviga- tion bar with submenus, the labels and partial functionality of which are populated through XML. P u s h Y o u r s e l f ! Download from Wow! eBook <www.wowebook.com> Part V: Input/Output 406 An XML-Based Navigation System The Directory Structure and Source Files Before looking at the ActionScript for this exercise, we need to explain a couple of quick things about the project’s directory structure and source files. We’ve tried to use several of the key topics that we’ve learned throughout the book to approximate an average use of an XML-driven menu system. Highlights include: object-oriented design, embedded fonts, text formatting, TweenLite animations, loading external assets, drawing with vectors, filter effects, and, of course, parsing XML. The project directory, nav_bar_xml, includes the primary FLA file, LAS3Lab.fla, and document class, LAS3Main.as. The exercise also uses classes from the learningactionscript3 package (in the com directory) that we’ve been building throughout the book: com.learningactionscript3.loading.LoadURL Created in Chapter 13, this class can load text from a URL, and includes error checking, making it convenient for loading XML. com.learningactionscript3.ui.NavigationBarXML This class is the backbone of the system and is a new version of the NavigationBar class used in Chapter 6. It replaces that chapter’s array data with XML, adds submenus, and puts the whole system to work by adding a loader that the menu items can target for loading SWFs and images. import com.learningactionscript3.ui.MenuButtonMain This simple class essentially provides a text field and text formatting for the MenuButtonMain movie clip in the LAS3Main.fla library. import com.learningactionscript3.ui.MenuButtonSub This class dynamically creates submenu buttons that will be clicked to load visual content at runtime. In addition, the exercise uses classes that are developed by others and are not part of any default ActionScript 3.0 distribution, including a few classes from TweenLite (the ActionScript tweening platform discussed in Chapter 7), and a modified version of Adobe’s SafeLoader class (the class designed to load SWFs that contain TLF instances without error, discussed in Chapter 13). The last parts of the exercise directory are the XML data and content for load- ing. The XML file that populates the menus is called nav.xml and is found inside a directory called data, and the content ready for loading, and specified in paths in the XML data, is found inside the projects directory. N OT E The navigation menu system in this chapter is an enhancement of the ver- sion in Chapter 6. We elected, however, not to replace the older classes to allow you to compare the classes and see the evolution of the code. Instead, we placed the new and revised classes in the com. learningactionscript3.ui package. Download from Wow! eBook <www.wowebook.com> An XML-Based Navigation System Chapter 14: XML 407 The Library of the FLA The main FLA file requires three symbols in its library: ArialBold ArialRegular These are embedded font symbols containing bold and plain versions of the Arial font with linkage class names of ArialBold and ArialRegular, respectively. Although embedded fonts in a SWF ensure that viewers don’t need to have the fonts installed in their computer, this is not true of editing an FLA. If you prefer, you can substitute your own fonts and then either use the same linkage class names or update the code accordingly. MenuButtonMain This is a movie clip that looks like a tab-shaped button. The class of the same name provides the text field and text formatting needed to display the tab’s text label. The XML and Classes Now we’ll being looking at the code behind the project. We’ll start by show- ing you an excerpt of the XML data file, and then discuss each of the classes that you’ll write. We’ll also explain the usage of related, third-party classes. XML You can look at the XML document any time, but the following excerpt is representative of the data: <nav> <menus> <button label="MOTION"> <project label="flocking" path="projects/motion/worm.swf"> Flocking with Zeno's paradox </project> <project label="point at" path="projects/motion/point.swf"> Pointing at the mouse position </project> </button> </menus> </nav> The root node, <nav>, has a child node, <menus>, which contains the data for all menus. Each menu is delineated by a <button> node, which corresponds to the main menu button. This node has a label attribute, which holds the text used for the main menu button text label. Within each <button> node are multiple child nodes called <project> (two are shown in the excerpt for brevity). Collectively, these make up the submenu for each menu. Each <project> node corresponds with one button in the submenu, and has an attribute called label. This is used to populate the text Download from Wow! eBook <www.wowebook.com> Part V: Input/Output 408 An XML-Based Navigation System label of the submenu button. It also has a path attribute, used to load the cor- responding content, and a text node, which we’ll use in Chapter 15 to display a brief blurb about the loaded asset. LAS3Main (document class) The document class is pretty straightforward. It loads the XML data, creates a SafeLoader for loading content and a mask for masking the content to an area below the menus, and initializes the menus. Lines 1 through 10 declare the package and import required classes, including SafeLoader, and two custom classes, CustomURLLoader and NavigationBarXML. Line 12 declares the class, including extending MovieClip so it can easily be used as a document class. Finally, lines 14 through 16 create three private properties for the CustomURLLoder, XML, and SafeLoader instances, respectively. 1 package { 2 3 import flash.display.Graphics; 4 import flash.display.MovieClip; 5 import flash.events.Event; 6 import flash.filters.DropShadowFilter; 7 import flash.net.URLRequest; 8 import fl.display.SafeLoader; 9 import com.learningactionscript3.loading.CustomURLLoader; 10 import com.learningactionscript3.ui.NavigationBarXML; 11 12 public class LAS3Main extends MovieClip { 13 14 private var _menuLdr:CustomURLLoader; 15 private var _xml:XML; 16 private var _loader:SafeLoader; The class constructor occupies lines 18 through 22 and creates an instance of the CustomURLLoader class to load the external data. Discussed in Chapter 13, this class does all the loading work for us and dispatches an Event.COMPLETE event when the loading is finished. Line 20 adds an event listener to trap this event and call onLoadXML(). Once the XML is loaded, the onLoadXML() method uses a try catch block to attempt to parse the XML. It retrieves the data from the data property of the CustomURLLoader instance and tries to instantiate an XML object using that data (line 26). If successful, it calls the initLoader() and initMenus() meth- ods (lines 27 and 28, respectively). If the data can’t be parsed as XML, it traces an error (lines 30 and 31). 17 //constructor and xml load 18 public function LAS3Main() { 19 _menuLdr = new LoadURL("data/nav.xml"); 20 _menuLdr.addEventListener(Event.COMPLETE, onLoadXML, 21 false, 0, true); 22 } 23 24 private function onLoadXML(evt:Event):void { 25 try { Download from Wow! eBook <www.wowebook.com> . contains “Learning ActionScript 3. 0. ” The result appears in lines 5 through 7. 1 var las3Data:XML = <book /> 2 las3Data.title = "Learning ActionScript 3. 0& quot;; 3 trace(las3Data); 4 /* 5. fl.display.SafeLoader; 9 import com.learningactionscript3.loading.CustomURLLoader; 10 import com.learningactionscript3.ui.NavigationBarXML; 11 12 public class LAS3Main extends MovieClip { 13 14 private var. { 2 3 import flash.display.Graphics; 4 import flash.display.MovieClip; 5 import flash.events.Event; 6 import flash.filters.DropShadowFilter; 7 import flash.net.URLRequest; 8 import fl.display.SafeLoader; 9

Ngày đăng: 06/07/2014, 18:20