Section 9.6. XML Message


9.6. XML Message

Document, Format, Hierarchical, PlainOldXML, POX, Semantic, Structured, XML

Figure 9-8. XML Message


9.6.1. Devloper Story

Dave is creating an Ajax search engine. The results are offered as a RESTful Service, so that external developers can create their own interface. The results are presented as XML, and Dave's own search interface pulls it down with an XMLHttpRequest call, then transforms the result to HTML.

9.6.2. Problem

How can you transfer data between server and browser?

9.6.3. Forces

  • Ajax Apps require messages to be transmitted back and forth.

  • Both browser and the server must be able to access the message. That usually means the format must be easily accessed in JavaScript as well as whichever server-side language is used.

9.6.4. Solution

Pass messages between server and browser in Extensible Markup Language (XML) format. It's feasible to pass XML in both directions. On the server side, it's a common way to expose structured data as text, and browser-side applications can download XML with an XMLHttpRequest Call and parse it in different ways. Where the browser needs to upload some complex data, it's fairly easy to serialize the data as XML and upload it in the body of an XMLHttpRequest Call.

XML is the definitive standard for data transfer across the industry, so just about any server-side development language has comprehensive support. The great advantage of XML over custom formats is the massive base of supporting frameworks, libraries, editors, and general tools. How you deal with XML on the server is language-specific, and a few choices are outlined in "Decisions," next. However you do it, make sure the server presents XML content with the appropriate header to ensure its handled correctly by XMLHttpRequest:

   Content-type: text/xml 

As the name implies, XMLHttpRequest was developed with XML transfer in mind. To retrieve an object with an XMLHttpRequest, first point it to a URL known to serve XML:

   xReq.open("GET","http://ajaxify.com/run/portal/drilldown/drilldown.phtml                     ?categoryName=Overviews",true); 

When XMLHttpRequest delivers a response, the response can either be interpreted as a DOM object or plain-text:

   var domObject = xReq.responseXML   alert(domObject) // Outputs "[Object]" (IE)                    // or "[object XML Document]" (Firefox)   var xmlString = xReq.responsetText   alert(domObject) // Outputs the whole string                    // i.e. "<category ...> ... </category>" 

In most cases, you want to use responseXML because it gives you a well-structured DOM object: a hierarchical structure that can be navigated using industry-standard conventions. With recent browsers, you can rely on some basic parsing functionality to interrogate DOM objects. HowToCreate has a good list of DOM traversal functions (http://www.howtocreate.co.uk/tutorials/texterise.php?dom=1) and many of the Ajax Patterns demos perform such parsing (e.g., the Basic Wiki Demo; see http://ajaxify.com/run/wiki).

If you're parsing XML, consider delegating to a cross-browser library. Sarissa (http://sarissa.sourceforge.net), for example, has a variety of cross-browser XML manipulation routines. Another library, Interactive Website Framework (IWF) (http://sourceforge.net/projects/iwf/), simplifies XML expressions. Instead of the following standard DOM query:

   var node = doc.documentElement.firstChild.firstChild.getAttribute("size"); 

you can write this:

   var node = doc.groceries.frozen[0].pizza[0].size; 

With a DOM object representing server data, the receiver can do one or more things:

  • Transform the XML into some HTML. (See "Decisions," next.)

  • Interrogate it to decide what to do next.

  • Store it for later use in an XML Data Island.

  • Modify it based on client state and upload it again.

This discussion has mostly focused on downloading XML from server to browser. That's the most common direction, but XML can also flow upwards too. It's sometimes easier to upload complex data as an XML document than as a set of CGI-style variables. To do this with XMLHttpRequest, you simply pass in the whole XML string as the argument to send( ). You'll also need to ensure the transport type is suitabletypically, POST (or PUT).

   xReq.send(xmlString); 

The XML string being sent usually represents browser state or user input. Most often, it's simply built up with some manual coding, appending strings together and including variables where appropriate. However, you can also use a library like Sarissa or Anders Noras's XmlSerializer (http://dotnetjunkies.com/WebLog/user/Profile.aspx?UserID=1095) to convert from a DOM objector some other objectinto an XML string.

Finally, a note of caution. "XML" is the X in "AJAX," so it's sometimes considered a core Ajax technology. And its association with XMLHttpRequest also strengthens the argument for XML Messages. However, don't let all this make you feel obligated to use XML Messages. XMLHttpRequest supports transfers in any plain-text format, and it's fine to use Plain-Text Messages in many situations. XML is relatively simple, and there's good browser support, but sometimes it just doesn't fit the bill. The "Solution" for Plain-Text Message compares the two approaches in more detail.

9.6.5. Decisions

9.6.5.1. How will the server generate XML?

There are many ways the server might generate XML messages:

  • By using custom code that hand-creates the XML string.

  • By building up a DOM object and serializing it.

  • By using a generic framework to convert standard data structures into XML.

  • By retrieving existing XML documents from the filesystem or external sources.

9.6.5.2. Will you specify a DTD or Schema?

When you pass XML Messages back and forth, each end must assume the same document format. That's a standard requirement with XML, and you can define the format precisely using a separate document: either a Document Type Definition or a stricter XML Schema document.

9.6.5.3. When the browser needs to render the message, how it will transform the XML?

The browser doesn't always need to render incoming XML messagessometimes it just uses the data. But, for situations when it does render the XML, there are a few options. In all cases, the script is building up some HTML, which will then be injected onto a DOM element by setting its innerHMTL property to the HTML string.


Manual JavaScript Conversion

For simple messages, you might find it easier to just perform a little parsing and manually create an HTML string.


XSLT

If you have the skill base and a suitable framework for the browsers you're targeting, Browser-Side XSLT allows for powerful conversion of XML.


Templating

Sometimes, Browser-Side Templating is a happy medium between the above two approaches. You still have to parse the XML document somehow, but the HTML generation is more straightforward.

9.6.6. Real-World Examples

9.6.6.1. Netflix Top 100

When you roll over a movie title in the Netflix Top 100 (http://www.netflix.com/Top100#), a balloon soon appears with summary details (Figure 9-9). After the rollover, an XMLHttpRequest Call occurs, which receives movie details like this:

   <MOVIES>   <MOVIE  POS="17" DS="0">     <TITLE>Kill Bill: Vol. 2</TITLE>     <SYNOPSIS>In this film noir tale written ... </SYNOPSIS>     <DETAILS RATED="R" RELYEAR="2003" GENRE GENRENAME="Action &&& Adventure"/>     <STARRING>       <PERSON  NAME="Uma Thurman"/>       <PERSON  NAME="Lucy Liu"/>     </STARRING>     <DIRECTOR>       <PERSON  NAME="Quentin Tarantino"/>     </DIRECTOR>   </MOVIE>   </MOVIES> 

Figure 9-9. Netflix


9.6.6.2. Protopage

Protopage (http://protopage.com) is a portal-style application with excellent personalization capabilities. Each time you change something on the page, a command is uploaded to the server via an XMLHttpRequest Call. For example, here's what the browser sent when I moved a Portlet around:

 <command account protopage protopagePath="mahemoff" name= "save-panel-geometry">   <param name="id">129644</param>   <param name="left">216</param>   <param name="top">476</param>   <param name="width">423</param>   <param name="height">71</param>   <param name="collapsed">false</param>   <param name="zIndex">33</param>   <param name="verticalScrollProportion">0</param> </command> 

9.6.6.3. Google Maps

Google Maps is perhaps the most famous usage of XML Messages. Meta-information is downloaded as XML and rendered with Browser-Side XSLT.

9.6.7. Code Refactoring: AjaxPatterns XML Sum

The Basic Sum Demo (http://ajaxify.com/run/sum) uses a Plain-Text Message to transfer the sum result from server to browser. So if the browser sends a GET query requesting the sum of 4 and 8, the entire response is "12." That works fine, but sometimes we'd like a response to contain the original query tooit's convenient for caching, for instance (see Browser-Side Cache [Chapter 13]). If we're going to provide the original figures of the sum, the data's becoming a bit more complexwe now have a list as well as different types of data. To keep the format self-describing, let's refactor to XML.

The XML Sum Demo (http://ajaxify.com/run/sum/xml) behaves the same as the original version, but the server side returns results like this (http://ajaxify.com/run/sum/xml/sumXML.php?figure1=4&figure2=8&figure3=):

 <sum>   <inputs>     <figure >4</figure>     <figure >8</figure>     <figure ></figure>   </inputs>   <outputs>12</outputs> </sum> 

To avoid confusion, the server-side service is now called sumXML.php, and reflecting the new location is the only change required to the browser call. The server-side service has been altered to output the full XML. Note the XML content-type declaration in the header, which is necessary for the XMLHttpRequest Call.

   <?     header("Content-Type: text/xml");     $sum = $_GET["figure1"] + $_GET["figure2"] + $_GET["figure3"];     echo <<< END_OF_FILE   <sum>     <inputs>       <figure >{$_GET["figure1"]}</figure>       <figure >{$_GET["figure2"]}</figure>       <figure >{$_GET["figure3"]}</figure>     </inputs>     <outputs>$sum</outputs>   </sum>   END_OF_FILE   ?> 

In this refactoring, the figures aren't used, but the sum is still required. The callback function therefore navigates through the response XML Message to obtain the sum figure.

   function onSumResponse(xml, headers, callingContext) {     var sum = xml.getElementsByTagName("outputs")[0].firstChild.nodeValue;     self.$("sum").innerHTML = sum;   } 

9.6.8. Alternatives

9.6.8.1. Plain-Text Message

As mentioned earlier in the "Solution," XML can often be overkill for simple messages, and Plain-Text Messages (see earlier in this chapter) are worth considering as an alternative.

9.6.8.2. JSON Message

Just like XML Message, JSON Message is a suitable representation for data of various complexities. The "Alternatives" section of JSON Message compares the two formats.




Ajax Design Patterns
Ajax Design Patterns
ISBN: 0596101805
EAN: 2147483647
Year: 2007
Pages: 169

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net