Introducing AJAX - Part 2
Introducing AJAX - Part 2
By Ed Woychowsky
2.5.1 XML
In its simplest form, XML is nothing more than a text file containing a single well-formed XML
document. Come to think of it, the same is pretty much true in its most complex form as well. Looking
past all of the hype surrounding XML, it is easy to see that XML is merely the text representation of
self-describing data in a tree data structure. When this is understood, all that is left are the nitty-gritty
little details, like "What's a tree data structure?" and "How exactly does data describe itself?"
A tree data structure is built of nodes, with each node having only one node connected above it, called a
parent node. The sole exception to this rule is the root node, which has no parent node. Nodes can also
have other nodes connected below, and these are called child nodes. In addition, nodes on the same
level that have the same parent node are called children. Figure 2-2 is a graphical representation of a
tree data structure.
2.6.1 XSLT
XSLT is an XML-based language that is used to transform XML into other forms. XSLT applies a style
sheet (XSLT) as input for an XML document and produces output—in most cases, XHTML or some
other form of XML. This XHTML is then displayed on the browser, literally in the "wink of an eye."
One of the interesting things about XSLT is that, other than the XML being well formed, it really
doesn't make any difference where the XML came from. This leads to some interesting possible sources
of XML. For example, as you are probably aware, a database query can return XML. But did you know
that an Excel spreadsheet can be saved as XML? XSLT can be used to transform any XML-derived
language, regardless of the source.
Listing 2-9 shows a simple Internet Explorer–only web page along the same lines as the earlier
examples. By using XSLT and the XMLHttpRequest object to retrieve both the XML and XSLT
shown in Listing 2-10, it is extremely flexible. This is because after the initial page is loaded, any
conceivable page can be generated simply by changing the XML and/or the XSLT. Sounds pretty
powerful, doesn't it?
Listing 2-9 A Simple IE-Only Web Page
1 <html>
2 <head>
3 <title>AJAX Internet Explorer Flavor</title>
4 <script language="javascript">
5 var dom = new ActiveXObject('MSXML2.FreeThreadedDOMDocument.3.0');
6 var xslt = new ActiveXObject('MSXML2.FreeThreadedDOMDocument.3.0');
7 var objXMLHTTP;
8
9 /*
10 Obtain the initial XML document from the web server.
11 */
12 function initialize()
13 {
14 doPOST(true);
15 }
16
17 /*
18 Use the XMLHttpRequest to communicate with a web service.
19 */
20 function doPOST(blnState) {
21 var strURL = 'http://localhost/AJAX/msas.asmx';
22
23 objXMLHTTP = new ActiveXObject('Microsoft.XMLHTTP');
24
25 objXMLHTTP.open('POST',strURL,true);
26
27 if(blnState)
28 objXMLHTTP.setRequestHeader('SOAPAction','http:// tempuri.org/getState');
29 else
30
31 objXMLHTTP.setRequestHeader('SOAPAction','http://tempuri.org/getXML');
32
33 objXMLHTTP.setRequestHeader('Content-Type','text/xml');
34
35 objXMLHTTP.onreadystatechange = stateChangeHandler;
36
37 try
38 {
39 objXMLHTTP.send(buildSOAP(blnState));
40 }
41 catch(e)
42 {
43 alert(e.description);
44 }
45 }
46
47 /*
48 Construct a SOAP envelope.
49 */
50 function buildSOAP(blnState) {
<html> <head> <title>AJAX Internet Explorer Flavor</title> <script language="javascript"> var dom
= new ActiveXObject('MSXML2.FreeThreadedDOMDocument.3.0'); var xslt = new
ActiveXObject('MSXML2.FreeThreadedDOMDocument.3.0'); var objXMLHTTP; /* Obtain the initial
XML document from the web server. */ function initialize() { doPOST(true); } /* Use the
XMLHttpRequest to communicate with a web service. */ function doPOST(blnState) { var strURL =
'http://localhost/AJAX/msas.asmx'; objXMLHTTP = new ActiveXObject('Microsoft.XMLHTTP');
objXMLHTTP.open('POST',strURL,true); if(blnState)
objXMLHTTP.setRequestHeader('SOAPAction','http:// tempuri.org/getState'); else
objXMLHTTP.setRequestHeader('SOAPAction','http://tempuri.org/getXML');
objXMLHTTP.setRequestHeader('Content-Type','text/xml'); objXMLHTTP.onreadystatechange =
stateChangeHandler; try { objXMLHTTP.send(buildSOAP(blnState)); } catch(e)
{ alert(e.description); } } /* Construct a SOAP envelope. */ function buildSOAP(blnState) { var
strSOAP = '<?xml version="1.0" encoding="UTF-8"?>'; strSOAP += '<soap:Envelope
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">'; strSOAP += '<soap:Body>'; if(blnState)
{ strSOAP += '<getState xmlns="http://tempuri.org/">'; strSOAP += '<state_abbreviation/>'; strSOAP
+= '</getState>'; } else { strSOAP += '<getXML xmlns="http://tempuri.org/">'; strSOAP +=
'<name>xsl/state.xsl</name>'; strSOAP += '</getXML>'; } strSOAP += '</soap:Body>'; strSOAP +=
'</soap:Envelope>'; return(strSOAP); } /* Handle server response to XMLHTTP requests. */ function
stateChangeHandler() { if(objXMLHTTP.readyState == 4) try { var work = new
ActiveXObject('MSXML2.FreeThreadedDOMDocument.3.0');
work.loadXML(objXMLHTTP.responseText); switch(true)
{ case(work.selectNodes('//getStateResponse').length != 0):
dom.loadXML(objXMLHTTP.responseText); doPOST(false); break;
case(work.selectNodes('//getXMLResponse').length != 0): var objXSLTemplate = new
ActiveXObject('MSXML2.XSLTemplate.3.0');
xslt.loadXML(work.selectSingleNode('//getXMLResult').firstChild.xml); objXSLTemplate.stylesheet =
xslt; var objXSLTProcessor = objXSLTemplate.createProcessor; objXSLTProcessor.input = dom;
objXSLTProcessor.transform(); document.getElementById('select').innerHTML =
objXSLTProcessor.output; break; default: alert('error'); break; } } catch(e) { } } </script> </head>
<body onload="initialize()"> <div id="select"></div> </html>
Listing 2-10 The XML and XSLT Part
1 <?xml version="1.0" encoding="UTF-8"?>
2 <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
3 <xsl:output method="html" version="1.0" encoding="UTF-8" indent="yes"/>
4
5 <xsl:template match="/">
6 <xsl:element name="select">
7 <xsl:attribute name="id">state</xsl:attribute>
8 <xsl:attribute name="name">selState</xsl:attribute>
9 <xsl:apply-templates select="//Table[country_id = 1]"/>
10 </xsl:element>
11 </xsl:template>
12
13 <xsl:template match="Table">
14 <xsl:element name="option">
<xsl:attribute name="value"><xsl:value-of select="state_abbreviation"/></xsl:attribute
15
>
16 <xsl:value-of select="state_name"/>
17 </xsl:element>
18 </xsl:template>
19</xsl:stylesheet>
view plain | print | ?
<?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="html" version="1.0"
encoding="UTF-8" indent="yes"/> <xsl:template match="/"> <xsl:element name="select">
<xsl:attribute name="id">state</xsl:attribute> <xsl:attribute name="name">selState</xsl:attribute>
<xsl:apply-templates select="//Table[country_id = 1]"/> </xsl:element> </xsl:template> <xsl:template
match="Table"> <xsl:element name="option"> <xsl:attribute name="value"><xsl:value-of
select="state_abbreviation"/></xsl:attribute> <xsl:value-of select="state_name"/> </xsl:element>
</xsl:template> </xsl:stylesheet>
2.8 Summary
This chapter started with a brief introduction to Ajax that included some of the origins and problems
associated with using "mad scientist stuff," such as the accusations of attempting to pass off a mock-up
as an actual application and the inability to describe just how something works. Of course, some people
still will think Corinthian helmets and hoplites at the very mention of Ajax, but you can't please
everyone.
Next there was a brief outline of the philosophy behind Ajax, which centers on the idea of not
bothering the server any more than is necessary. The goal is that of reducing, if not eliminating, the
unload/reload cycle—or "blink," as some call it. The Ajax philosophy also includes the idea of making
the client's computer work for a living. After all, personal computers have been around in some form
for close to 30 years; they should do some work—take out the trash, mow the lawn, or something.
Finally, I presented the three simple examples of how Ajax can be implemented. The first example,
although not quite Ajax, does much to show something of the first attempts to implement a web
application with the feel of a Windows application. Although it's primitive by today's standard, it is still
better than 99 percent of the web pages out there today.
Using the XMLHttpRequest object, the second example is dead on as to what is expected from an
Ajax application. Broken are the bonds that limit updates to the unload/reload cycle that has been
confronting us on the Web since Day 1. In addition, XML plays well with the concept of reducing
traffic.
The third and final example pushes Ajax to the current limits with the addition of XSLT to the mix.
XSLT allows XML to be twisted and stretched into any conceivable shape that we can imagine. No
longer are our creations limited to the parts that we can dig up here and there; we can make our own
parts on demand.