Virtual Pet: an Exercise in XML and XSLT

Virtual Pet: an Exercise in XML and XSLT

<p>VIRTUAL PET: AN EXERCISE IN XML & XSLT Jeanine Meyer Mathematics/Computer Science & New Media Purchase College/State University of New York Purchase, New York, 10577 914-251-6679 [email protected]</p><p>ABSTRACT EXtensible Markup Language (XML) and eXtensible Stylesheet Language: Transformations (XSLT) are tools for creating and maintaining content-rich applications, such as Web documents. A virtual pet is a computer representation of a [simple] model of pet behavior incorporating mechanisms for owner actions. Starting with a HTML/JavaScript virtual dog script, the author describes the use of eXtended Markup Language (XML) and eXtended Stylesheet Language: Transformations (XSLT) to produce a generalized system for producing simulations. The project has been used in a course on creating user interfaces.</p><p>BACKGROUND A virtual pet is a computer representation of a [simple] model of pet behavior incorporating mechanisms for owner actions. One example would be a virtual dog that can be fed or petted. If the virtual dog is fed too little or too much, it dies. When the virtual dog is petted, the dog may wag its tail, but it may, instead, show its teeth in a snarl. This behavior appears unpredictable since it is based on a calculation using a pseudo-random function with input the length of time since the last feeding. Such applications are amusing to students and also serve more profound roles in teaching. Experienced practitioners can learn from simple examples how tools work and can synthesize an assortment of features to build complex applications. Students generally cannot do so. The ability to put different features together may be the defining trait of an expert. At Purchase College/State University of New York, we decided to offer a course called Creating User Interfaces. This course focuses on analysis of usability and functionality and also critical technologies for a variety of media, including the Web (XML, XSLT), wireless phones (WML, WMLS) and directed speech recognition (VoiceXML). It is taken by mathematics/computer science majors, New Media majors and Continuing Education students. EXtended Markup Language (XML) is emerging as a significant technology for its role in Web applications, as the basis for connecting different applications and as the basis for other languages, including eXtended Stylesheet Language: Transformations (XSLT), Wireless Markup Language (WML), and VoiceXML. XSLT is used to specify how an XML document is to be transformed into something else, typically, HyperText Markup Language. The XML and XSLT combination supports a structured, robust approach to formatting documents. Examples of XML and XSLT typically show contact lists, soccer scores and, in an attempt to reach the youth market, CD catalogs. The underlying content is routine and the resulting displays, though varied, are not especially compelling. That is, the non- expert may fail to appreciate the power of the technology. It was the author's experience that students had trouble with XML because examples seemed too obvious and troubles with XSLT because the pattern-matching approach to transformation was different from ordinary programming. The virtual pet example demonstrates that XML content can be multifaceted, even including code fragments. Moreover, this example, and others like it, affords students opportunities to integrate graphics and story telling into their projects. Simulations, along with games, have the distinct feature that students run their programs more than once, a necessary attribute of real-world testing. A basic virtual dog application, coded directly in HTML and JavaScript, is used in our course entitled Creating Web Documents. This is a required course for New Media majors and a popular elective for others. The generalized virtual pet application is one of several examples (following the standard examples showing contact list and soccer scores) to demonstrate the power of XML and XSLT in a course entitled Creating User Interfaces. </p><p>VIRTUAL DOG IN HTML AND JAVASCRIPT The original virtual dog was implemented using HTML and JavaScript. The initial screen shows that the dog is in the normal state, as indicated by the graphic and the label. A textbox shows the dog's weight. The next screen shot shows an underfed dog.</p><p>If the situation continues with no feeding of the dog, the dog dies. Just as it is possible to starve the virtual pet, it is also possible to overfeed the pet. Overfeeding also can lead to the death of the virtual pet</p><p>The action of petting the dog can lead to a happy dog wagging its tail or a dog that snarls. The tail wagging dog is implemented using an animated gif file. The original implementation of the virtual dog was done by 'straight' hand coding of HTML and JavaScript. The HTML consists of a single, named image tag, a <form> element with 2 input tags (used to display the status and the weight), and 4 hyperlinks using JavaScript calls for the 4 actions. JavaScript has functions that establish timed events and the associated event handling. The call tid = setInterval("change()", 1000); establishes that every 1000 milliseconds a call is to be made to the function change(). The variable tid is set to a number that identifies this particular timed event. A call to window.clearInterval(tid); turns off the timed event pointed to by the variable tid. The change() function examines the weight of the dog, held in a variable and contains a nested if statement to determine what image file is to be placed in the image tag. Note that the model is similar to but not, strictly speaking, a finite state machine because of the presence of the weight variable as well as the calculation of time done to produce time since last feeding. The actions designated by the 4 labels are implemented using HTML <a> tags. For example, the Pet Dog action is implemented using <a href="javascript:petdog();">Pet dog</a> where petdog() designates a function. This function performs a calculation using the Math.random() method of JavaScript. Depending on the results, the wag.gif or the mean.gif is placed in the image tag. function petdog() { function header var e; variable to hold elapsed time var p; variable to hold limit var r; variable to hold random value e = seconds_elapsed(); set time elapsed since feeding p = 1-(e/20); calculate limit if (p<.1) { re-adjust limit if less than .1 p = .1; } r = Math.random(); get random value if (r<p) { compare to limit positive outcome: show wagging dog document.dogpic.src="wag.gif"; } else { negative outcome: show mean dog document.dogpic.src="mean.gif"; } close else } close function</p><p>The result of this formulation is that there is always a chance of either friendly or mean behavior on the part of the dog. It is part of the appeal of the project, though it also led one student to say, "It is obvious that you don't like dogs."</p><p>VIRTUAL PET IN XML AND XSLT An XML/XSLT version of the virtual dog would mean that the model of the pet behavior could be separated from the details of the implementation and either one could be modified or completely changed. The application really would be 'virtual pet' with other people able to define their own pet. However, to do that, it is necessary to abstract the content. The framework chosen here is to define a pet behavior in terms of states, state variables, actions, and the base interactions done at each iteration of the simulation. For the generalized virtual pet, the pet designer gives each state a name, furnishes a graphics file, and defines a set of zero or more switch conditions. A switch condition contains the parts that when put together are the code to check for a condition and then change to another state. It can designate only the new state to change to if the condition is true or both true and false new states. At least one state is designated the starting state. Zero or more states can be designated stopping states. State variables are exactly what they sound like: variables that maintain information. They can be viewed as a way of parameterizing any of the states. An obvious candidate for a state variable for this application is weight. Actions are implementations for player moves. In this case, the actions correspond to the Pet Dog and Feed Dog links. The two other links, starting and stopping, are created automatically for all applications. This application assumes some sort of cycle. However, two features of that cycle are up to the individual specification for each virtual pet. These are the timing interval, specified by a state variable named interval and the code that is executed each interval (in addition to the state switch conditions). This code is designated as the intervalaction. The XML file The design of the XML file follows the requirements indicated in the previous section. It is important to point out to students that someone else may have done things differently. For the simple XML examples such as a contact list, most everyone would define the XML tags the same way. It is only when applications reach some degree of complexity that differences can appear. Notice especially the use of attributes versus child elements. The information for specifying a virtual pet is to  animal name  any number of state variables. One must have the name interval.  any number of states. Each state will have a name, label, associated image file, and zero or more switch conditions. One state must have an attribute of start equal to yes. Note that XML rules requires attributes to have values: it would not be valid to have <state start ….>. Zero or more states could have the attribute of stop set to yes.  any number of actions. Actions have labels and procedures. Each action generates a button.  interval action. This specifies code executed at each iteration of the simulation.</p><p>The scripting language for the code in the switch conditions, actions and the interval action is in JavaScript. This could be in any language, for example, VBScript, though that would require modest changes to the XML and XSLT. The following is an outline for the vdog.xml file.  XML standard opening instructional tags, including a pointer to the XSL file  The root node is the <animal> tag. Everything is contained in this tag.  The animalname tag contains the name output to the title of the HTML document.  There are 4 state variables (statevar): interval, elapsed, wagtime and weight. An attribute indicates if a variable is to be shown. The contents of the element are the initial values of these variables.  There are 7 states: normal, fat, fatdead, thin, thindead, wag, and mean. Attributes indicate the start and the stopping states. Both fatdead and thindead are stopping states. A switch condition contains a condition tag and a truestate tag containing the state to switch to if the condition is true. The implementation allows for a falsestate tag, but it was not used for this example.  There are two designated actions: petting the dog and feeding the dog. These elements contain procedure names and procedures.  The so-called intervalaction specifies code to add the interval value to the elapsed variable and to decrement the weight by one.</p><p>The full text of vdog.xml, that is, the XML content that will be transformed into a replica of the original HTML/JavaScript application, is in the Appendix. Implementation of virtual pet using XSLT The transformation of the XML content into a working project is done using an XSLT file, named virtual.xsl. It must create the HTML document with all the necessary JavaScript coding, including variables and functions in the head section and calls to functions in the <a> tags. The XSLT file operates in what is called pull processing to produce the final result. The required elements are selected and manipulated as needed as opposed to using multiple templates and apply-templates to push nodes out to the HTML document. The XSLT program examines certain nodes, for example, the state nodes, more than one time. The XSLT operates in both a procedural and pattern-matching style. Here is an outline of the XSLT file. The complete XSL file is supplied in the Appendix.</p><p> XML and XSLT standard boilerplate  One template: for the topmost node: animal  Set a variable interval to hold the value of the statevar named interval  Output the html and head tags. Include in the title the value of the animalname tag  Output the tags for JavaScript in the head section. Note that the contents of the script element are not commented out. This could be done using &lt; and &gt;  Output the declaration (var statement) of a variable called curstate. It is initialized to be the value of the state with attribute start equal to yes.  Output declarations for all the state variables designated in the xml file.  Output a declaration for a variable called tid, used by setInterval and clearInterval  Output declarations and initializations for two arrays, statepictures and statelabels. These are to be associative arrays. The index is the state name and the value is the picture image file and the label, respectively. The initialization is done using the for-each construct.  Output the change function. This starts with the content of the intervalaction element. The next part of the change function is a switch statement, with each case corresponding to a state. Within each case, each switchcondition produces an if test with condition, code for the true clause and, optionally, code for a false clause. The label for the current state and the picture for the current state are picked up using the associative arrays and placed in the <form> label tag and the image tag. Then, for each state variable designated as show='true', the value is placed in the appropriate <form> input tag. The last part of the change function concerns the states that are designated as stopping states. For each of these, code is output to test for that state being the current state. The contents of the if true clause is a call to stop the timing event using (window.clearInterval(tid)). Note the multiple meanings of 'name'.  The start and stop functions, which are constants, independent of the xml content, are output. A variable named started is used to alert players if they click the start button when play already has started.  For each action designated, functions are defined using the contents of the action elements. This ends the <script> and the <head> sections.  The <body> section starts with the image tag.  The next item is a <form> element. Notice that the <form> elements are output using one method of using XSL and, later, the <a> elements, are output using another. The <form> will contain an <input> element for the label for the current state plus one for each variable that is to be shown.  For each action designated, the XSLT outputs an <a> element with the href attribute written as a call to a JavaScript function.  Similarly, the XSLT outputs an a tag for calls to start() and stop(). </p><p>Opening the XML file, with its reference to an XSL file means that the View Source command displays the original XML file. To show the students that the XSL file does indeed produce a file resembling the one hand-coded directly in HTML, Instant Saxon (developed by Michael Kay) can be used to produce the HTML file. All these files, with an explanatory tutorial, as well as other XSL/XSLT examples, are reachable from the author's web site: http://newmedia.purchase.edu/~Jeanine. </p><p>OBSERVATIONS The generalized virtual pet application shows the benefits of separating content and formatting in a complex example. The content in this situation is the simulation: the states, the graphics portraying those states, the actions and the coding that defines the transitions. This content does include code. What the XSLT does is implement the simulation that has been defined by the XML document. This example does serve to demonstrate to students the power of the technologies by going beyond the examples typically found in textbooks. The resulting Web pages using this approach are intricate, interactive sites. The challenge in writing the XSLT is that you are writing code to write code, similar to producing a compiler. You need to distinguish between transformation of the XML and running of the resulting HTML and JavaScript. The complexity of the transformation and the resulting runtime application invoke student understanding in situations where the typical examples often fail. In addition, the fact that students can improve on their teacher's graphics or make other enhancements is an immediate incitement to action. Projects must be at a minimum level of complexity for this to be the case. One pair of students did a Virtual Drunk Robot and another student designed a fish bowl. The basic state change paradigm and the artful use of the random function open up new areas for students to explore. For example, students can be asked if the virtual pets are finite state automata (FSA) and if they are examples of non-deterministic machines. The answers are that the presence of state variables provide more computational power than FSA and that non-deterministic machines are for carrying out the branches concurrently and here, a fixed choice is made based on calls to the pseudo-random function. However, these concepts do provide inspiration and structure. Students did appreciate that at some point, you cannot 'hand-code' simulations without systematically defining state and state changes. Most importantly, students can envision how to take what they have learned in programming classes and integrate it into XML and XSLT projects. Appendix</p><p>XML file <?xml version="1.0" ?> <?xml-stylesheet href="virtual.xsl" type="text/xsl"?> <animal> <animalname>Dog</animalname> <statevar name="interval">1000</statevar> <statevar name="elapsed">0</statevar> <statevar name="wagtime">0</statevar> <statevar name="weight" show="yes">100</statevar> <state name="normal" start="yes"> <picture>dog.gif</picture> <label>Dog is normal.</label> <switchcondition> <condition>weight>120</condition> <truestate>fat</truestate> </switchcondition> <switchcondition> <condition>80>weight</condition> <truestate>thin</truestate> </switchcondition> </state> <state name="fat"> <picture>fatdog.gif</picture> <label>Dog is fat.</label> <switchcondition> <condition>120>weight</condition> <truestate>normal</truestate> </switchcondition> <switchcondition> <condition>weight>150</condition> <truestate>fatdead</truestate> </switchcondition> </state> <state name="fatdead" stopstate="yes"> <picture>fatdeaddog.gif</picture> <label>Dog is dead.</label> </state> <state name="thin"> <picture>thindog.gif </picture> <label>Dog is thin.</label> <switchcondition> <condition>weight>80</condition> <truestate>normal</truestate> </switchcondition> <switchcondition> <condition>60>weight</condition> <truestate>thindead</truestate> </switchcondition> </state> <state name="thindead" stopstate="yes"> <picture>thindeaddog.gif</picture> <label>Dog is dead.</label> </state> <state name="wagging"> <picture>wag.gif</picture> <label>Dog is wagging its tail.</label> <switchcondition> <condition>(wagtime++)>5</condition> <truestate>normal</truestate> </switchcondition> </state> <state name="mean"> <picture>mean.gif</picture> <label>Dog is angry. </label> <switchcondition> <condition>(wagtime++)>5</condition> <truestate>normal</truestate> </switchcondition> </state> <action label="Feed dog"> <procedurename>feeddog</procedurename> <procedure>weight=weight+10;elapsed=0; </procedure> </action> <action label="Pet dog"> <procedurename>petdog</procedurename> <procedure> wagtime=0; prewagcurrent=curstate; if (Math.random()>Math.min(elapsed/interval,19)/20) {curstate="wagging";} else {curstate="mean";}</procedure> </action> <intervalaction> elapsed=elapsed+interval; weight=weight-1; </intervalaction> </animal></p><p>Note that there is some slight of hand here: the artful use of the greater than sign (>) rather than the less than sign (<) in the conditionals has meant that the use of the entity &lt; or escaping code in CDATA sections could be avoided.</p><p>XSL file with comments</p><p><?xml version="1.0" ?> standard first line - <xsl:stylesheet version="1.0" standard reference xmlns:xsl="http://www.w3.org/1999/XSL /Transform" xmlns:fo="http://www.w3.org/1999/XSL /Format"> <xsl:output method="html" /> produce HTML - <xsl:template match="/animal"> match on animal node - <xsl:variable name="interval"> Will use value of interval node, so make it a variable <xsl:value-of extract value of the statevariable node select="/statevariable[@name='interval']" with the name 'interval' /> </xsl:variable> - <html> output standard HTML - <head> - <title> Virtual <xsl:value-of Include value of animalname node in select="animalname" /> </title> title - <script language="JavaScript" specify JavaScript. Note this is 'hard type="text/javascript"> coded' but could be made dependent on a value in the XML <xsl:text>var curstate='</xsl:text> Output var for curstate <xsl:value-of … and set it to whichever state had the select="state[@start='yes']/@name" /> start attribute equal to yes. <xsl:text>';</xsl:text> … and output semicolon - <xsl:for-each select="statevar"> This is an XSL loop to set up each of the state variables <xsl:text>var</xsl:text> Output the var to declare the variable <xsl:value-of select="@name" /> Output name <xsl:text>=</xsl:text> Output equal sign <xsl:value-of select="." /> The period refers to the value of the current statevar node <xsl:text>;</xsl:text> Output semicolon </xsl:for-each> End iteration over all statevar nodes var tid; The implementation requires a variable tid when using setInterval and clearInterval. <xsl:text>var statepictures=new Array(); The pictures and the labels for the var statelabels=new Array();</xsl:text> pictures are kept in parallel arrays. - <xsl:for-each select="state"> XSL loop for the states <xsl:text>statepictures['</xsl:text> Insert into the statepictures array <xsl:value-of select="./@name" /> Use the name attribute <xsl:text>']='</xsl:text> <xsl:value-of select="./picture" /> Use the picture attribute (giving the file name) <xsl:text>'; statelabels['</xsl:text> Ends the setting of an element of statepictures and starts the setting of an element of statelabels. <xsl:value-of select="./@name" /> Use the name attribute <xsl:text>']='</xsl:text> <xsl:value-of select="./label" /> Use the label attribute <xsl:text>';</xsl:text> </xsl:for-each> Ends the XSL loop going through the states - <xsl:for-each select="function"> Starts a loop through the functions <xsl:value-of select="." /> Outputs content as is. </xsl:for-each> Ends the XSL loop through functions <xsl:text>function change() {</xsl:text> Starts the definition of the simulation function called change <xsl:value-of select="intervalaction" /> Include the contents of the intervalaction as is. <xsl:text>switch (curstate) {</xsl:text> Start of switch statement - <xsl:for-each select="state"> Each state constitutes a case <xsl:text>case '</xsl:text> <xsl:value-of select="./@name" /> <xsl:text>':</xsl:text> - <xsl:for-each select="./switchcondition"> Within each state, each switchcondition leads to …. <xsl:text>if (</xsl:text> an if statement <xsl:value-of select="./condition" /> … using the contents of the condition <xsl:text>) { curstate='</xsl:text> Positive branch of the if means a change of state: assignment to curstate of the truestate value <xsl:value-of select="./truestate" /> <xsl:text>';}</xsl:text> - <xsl:if test="./falsestate"> If a falsestate has been specified, then <xsl:text>else { curstate='</xsl:text> an else clause is output to set curstate to <xsl:value-of select="./falsestate" /> .. the falsestate <xsl:text>';}</xsl:text> </xsl:if> </xsl:for-each> End switch conditions <xsl:text>break;</xsl:text> Output a break statement in-between cases in the switch statement </xsl:for-each> End consideration of a state <xsl:text>}</xsl:text> <xsl:text>document.f.label.value=statelab Set the label being displayed (in the els[curstate]; HTML body) and set the image being document.pic1.src=statepictures[curstate displayed (in the HTML body) to the ];</xsl:text> label and picture for curstate - <xsl:for-each For each statevar that is to be select="statevar[@show='yes']"> displayed <xsl:text>document.f.</xsl:text> set its displayed value <xsl:value-of select="./@name" /> output its name attribute <xsl:text>x.value=</xsl:text> … followed by an x to refer to the input in the form by this name <xsl:value-of select="./@name" /> set the value to the name <xsl:text>;</xsl:text> </xsl:for-each> End loop through statevar - <xsl:for-each Output code to check if the simulation select="state[@stopstate='yes']"> is to stop by iterating over all the states set as stopping states. <xsl:text>if (curstate=='</xsl:text> Output if statement for this particular state <xsl:value-of select="./@name" /> <xsl:text>') Output call to stop interval event { window.clearInterval(tid);}</xsl:text> </xsl:for-each> end iteration over stopping states <xsl:text>} var started = false; function Output set (constant) code for starting start() { if (started) {alert("Already and stopping. started!"); } else {started = true; tid=setInterval("change()",interval);} } function stop() { started = false; window.clearInterval(tid); }</xsl:text> - <xsl:for-each select="action"> XSL loop over each action <xsl:text>function</xsl:text> Output function definition <xsl:value-of select="procedurename" /> procedure name (to be referenced below) <xsl:text>() {</xsl:text> no arguments <xsl:value-of select="procedure" /> Output content of node <xsl:text>}</xsl:text> </xsl:for-each> End XML loop over actions </script> End script element <xsl:text /> </head> Standard HTML - <body> Standard HTML - <xsl:element name="img"> This is the start of the img tag to hold the picture of the pet - <xsl:attribute name="src"> src set to <xsl:value-of … the picture corresponding to the select="state[@start='yes']/picture" /> start = yes state </xsl:attribute> <xsl:attribute set the name attribute to the constant name="name">pic1</xsl:attribute> pic1 </xsl:element> <br /> - <xsl:element name="form"> Start of form that will hold values to be displayed - <xsl:attribute name="name"> <xsl:text>f</xsl:text> Form given a name to be referenced by the code </xsl:attribute> - <xsl:element name="input"> These are designated input field, but only used for output! - <xsl:attribute name="type"> Set up the type <xsl:text>text</xsl:text> … to be text </xsl:attribute> - <xsl:attribute name="name"> set the name <xsl:text>label</xsl:text> .. to be label </xsl:attribute> - <xsl:attribute name="value"> Set the (initial) value to be <xsl:value-of … the label corresponding to the start select="state[@start='yes']/label" /> state </xsl:attribute> </xsl:element> End input element - <xsl:for-each XSL loop to display all state variables select="statevar[@show='yes']"> that are to be displayed - <xsl:element name="input"> input element within the form - <xsl:attribute name="type"> type attribute set to <xsl:text>text</xsl:text> text </xsl:attribute> - <xsl:attribute name="name"> HTML attribute name <xsl:value-of select="./@name" /> to be set to value of XML attribute name. <xsl:text>x</xsl:text> Add 'x' to prevent confusion. </xsl:attribute> - <xsl:attribute name="value"> value attribute set to <xsl:value-of select="." /> contents of statevar, the initial value </xsl:attribute> </xsl:element> </xsl:for-each> End iteration over statevar nodes </xsl:element> End form element <hr /> - <xsl:for-each select="action"> XSL loop over all actions - <a href="javascript:{procedurename} Produce an <a> element that calls the ();"> corresponding procedure: the one named procedurename by XSL above. <xsl:value-of This is the label attribute of the action select="@label" /> </a> node. It is what the player sees. <xsl:text /> Outputs non-breaking space. </xsl:for-each> Ends XSL loop iterating over actions <a Output set (constant) code for button href="javascript:start();">Start play</a> to start play <xsl:text /> Inserts blank. <a Output set (constant) code for button href="javascript:stop();">Stop play</a> to stop play </body></html> Standard HTML </xsl:template> </xsl:stylesheet> Standard closing XSL</p><p>BIBLIOGRAPHY Michael Kay, XSLT 2nd Edition, Wrox Press, 2001</p><p>Tennison, Jeni, Beginning XSLT, Wrox Press, 2002</p>

View Full Text

Details

  • File Type
    pdf
  • Upload Time
    -
  • Content Languages
    English
  • Upload User
    Anonymous/Not logged-in
  • File Pages
    13 Page
  • File Size
    -

Download

Channel Download Status
Express Download Enable

Copyright

We respect the copyrights and intellectual property rights of all users. All uploaded documents are either original works of the uploader or authorized works of the rightful owners.

  • Not to be reproduced or distributed without explicit permission.
  • Not used for commercial purposes outside of approved use cases.
  • Not used to infringe on the rights of the original creators.
  • If you believe any content infringes your copyright, please contact us immediately.

Support

For help with questions, suggestions, or problems, please contact us