Today we will consider:
It can be useful to design an XSLT stylesheet which defines how to transform XML data retrieved from a web service into HTML, and therefore write an AJAX application without resorting to DOM parsing. To do this you use a JavaScript XSLTProcessor object. Below is some code which illustrates the use of the XSLTProcessor (based on the original article here). Imagine the flights.php script returns data of this format:
<flights> <flight> <number>101</number> <destination>New York</destination> <date>01/06/08</date> <time>11:00</date> </flight> <flight> <number>103</number> <destination>New York</destination> <date>01/06/08</date> <time>13:00</date> </flight> <flight> <number>105</number> <destination>New York</destination> <date>01/06/08</date> <time>15:00</date> </flight> </flights>Here is the AJAX / XSLT code:
var xslloaded = false;
var xsldoc;
function go()
{
// send ajax request
var request = new Ajax.Request
('http://solentairways.com/flights.php',
{ method: 'GET',
onComplete: callback}
);
}
function callback(xmlHTTP)
{
// send ajax request
var request = new Ajax.Request
('http://solentairways.com/flights.xsl',
{ method: 'GET',
asynchronous: false }
);
// Get the XSLT doc
var xsldoc = request.transport.responseXML;
if(window.XSLTProcessor)
{
var processor = new XSLTProcessor();
processor.importStylesheet(xsldoc);
var output = processor.transformToFragment
(xmlHTTP.responseXML, document);
var result=document.getElementById("result");
// Ensure the output <div> is blank
result.innerHTML="";
// append a DOM node (the fragment) to the div
result.appendChild(output);
}
else if (window.ActiveXObject)
{
var html = xmlHTTP.responseXML.transformNode(xsldoc);
var result=document.getElementById("result");
result.innerHTML = html;
}
else
{
alert("your browser can't handle this!");
}
}
Hopefully the code should be fairly straightforward:
Because we are generating a fragment of HTML, rather than a complete HTML page, we need to do things a bit differently in the XSLT. Here is the XSLT file we are using:
<?xml version="1.0"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="html" /> <xsl:template match="/flights"> <!-- Display all flights which aren't full --> <xsl:for-each select="flight[seats>0]"> <p> <strong>Number:</strong><xsl:value-of select="number" /> <br/> <strong>Destination:</strong> <xsl:value-of select="destination"/> <br/> <strong>Time:</strong><xsl:value-of select="time" /> <br/> </p> </xsl:for-each> </xsl:template> </xsl:stylesheet>We are not generating a complete XHTML document with this XSLT; instead we are creating a fragment of an HTML page. Because of this:
<xsl:output method="html">This is telling the XSLT processor that the output will be merely HTML, rather than a complete, valid XHTML document.
The method above is perhaps not 100% ideal as the XSLT is loaded synchronously - i.e. the browser waits while the XSLT is retrieved. This is fine for small XSLT stylesheets but might be a problem for a large one. This example illustrates loading the XSLT asynchronously - i.e. the user can continue to interact with the browser while the XSLT is being retrieved.
<?php
$a = $_GET['html'];
if ($a=='yes')
{
echo "<?xml version='1.0'?>"
echo "<?xml-stylesheet type='text/xsl' href='toHTML.xsl' ?>"
}
// Code to generate XML from the database follows....
?>
example.php?html=yeswill generate an HTML page by applying the XSL stylesheet toHTML.xsl to the XML data, while
example.phpwill simply generate the pure XML data, allowing the script to be used as a web service
You can combine AJAX, XSLT and SVG to produce an AJAX application which will fetch raw XML data from a server, transform it to SVG using an XSL stylesheet and then insert the SVG into a <div> on a web page. This exercise allows you to do this.
This will not work on Internet Explorer. However it does work on latest versions of Firefox, Opera and Safari.