Week 11: Combining XSLT with Other Technologies

Today we will consider:

Combining AJAX and XSLT

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:

Structure of the XSLT

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&gt0]">

<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:

Loading the XSLT asynchronously

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.

Conditionally applying XSLT stylesheets from server side scripts

For log book

Exercises

Standard exercise

  1. Make a copy of your AJAX code from week 3 (the AJAX front end which communicated with your web service) and save it in a week 11 folder. Also make a copy of your first XSLT stylesheet from last week (the one which looped through each song in the input XML and converted it to HTML) in the week 11 folder.
  2. Change your AJAX code so that it applies the XSLT stylesheet to the XML returned from the server and places the resulting HTML in a <div>, as in the example above.
  3. Modify your XSLT stylesheet so that it doesn't try to write out an entire XHTML document, but instead, an HTML fragment containing only the HTML for the songs, as in the example above.
  4. Upload all the files to Edward and test it out.

Advanced exercise - AJAX, XSLT and SVG

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.