Client-side XML transformations with Sarissa

(I’m not going to explain in detail what XML, XSL, or XPath are here. If you don’t know, check out w3school’s xml tutorial, xsl tutorial, and xslt tutorial)

I recently had the opportunity to work with client-side XML parsing, XSL transformations, and XPath for a project. The problem, as it usually manifests itself, is the fact that each browser tends to implement its own version of the DOM in its own way (if it implements it at all) and varying degrees of support for XPath and XSL.

I found two decent frameworks for dealing with the XML, XSL, and XPath. One is made by Google, called Google AJAXSLT. It is a pure-Javascript implementation of XSLT and XPath, so it is kind of slow, and the documentation is rather lacking. I also found a library called Sarissa which is a cross-browser wrapper for native XML handling. So it provides one interface to interact with the DOM functions but uses the underlying implementation so it is a lot faster than Google’s AJAXSLT.

It’s also easy to work with XML and you transformations. Let’s say I have a file on a webserver somewhere named test.xml, which looks like this:

<books>
  <book>
    <author>J.K. Rowling</author>
    <title>Harry Potter and the Sorcerer's Stone</title>
    <isbn>0439554934</isbn>
  </book>
  <book>
    <author>J.K. Rowling</author>
    <title>Harry Potter and the Chamber of Secrets</title>
    <isbn>0439554896</isbn>
  </book>
  <book>
    <author>J.K. Rowling</author>
    <title>Harry Potter and the Prizoner of Azkaban</title>
    <isbn>043965548X</isbn>
  </book>
</books>

And say you have an XSL stylesheet named test.xsl that looks like this:

<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:template match="/">
  <html>
  <body>
    <h1>My Favorite Books</h1>
    <table border="1">
      <tr bgcolor="#CCCCCC">
        <th>Author</th>
        <th>Title</th>
        <th>ISBN</th>
      </tr>
      <xsl:for-each select="books/book">
      <tr>
        <td><xsl:value-of select="author" /></td>
        <td><xsl:value-of select="title" /></td>
        <td><xsl:value-of select="isbn" /></td>
      </tr>
      </xsl:for-each>
    </table>
  </body>
  </html>
</xsl:template>

</xsl:stylesheet>

You can transform the XML by loading the Sarissa library and the Sarissa DHTML functions library in your HTML head:

<script type="text/javascript" src="sarissa.js"></script>
<script type="text/javascript" src="sarissa_dhtml.js"></script>

sarissa.js is required for the base Sarissa methods, and the sarissa_dhtml.js contains some AJAX tricks to update the content based on your XML document and your stylesheet.

I start by creating a simple Javascript function to get an XML document. It is sort of like an AJAX call, but it is synchronous because I want to block further action until I get the document. So its more like SJAX or just JAX. Yeah, that’s it…

function getXmlDocument(fileUrl)
{
    var xmlDocument = Sarissa.getDomDocument();
    xmlDocument.async = false;
    xmlDocument.load(fileUrl);
    if (Sarissa.getParseErrorText(xmlDocument) != Sarissa.PARSED_OK)
    {
	    alert(Sarissa.getParseErrorText(xmlDocument));
    }
	return xmlDocument;
}

All that does is creates a new DOM Document via Sarissa, and loads an XML file as defined in the parameter fileUrl. Next I create an init() function that runs when the HTML document loads. It is responsible for loading the XML file and the XSL stylesheet, and doing the actual transformation. Here it is:

function init()
{
	var xml       = getXmlDocument("test.xml");
	var xsl       = getXmlDocument("test.xsl");
	var processor = new XSLTProcessor();
	var results   = document.getElementById('results');

	processor.importStylesheet(xsl);
	Sarissa.updateContentFromNode(xml, results, processor);
}

My HTML page looks like this:

<body onload="init()">
  <div id="results"> </div>
</body>

Now that all the pieces are in place, when you load the HTML page, you end up with something like this:

My Favorite Books

Now, granted, you could always embed a link to an XSL stylesheet in the XML file and call it directly from an XSL compatible browser (i.e. most modern major browsers) but this is neat for applications where you want to have some web 2.0 goodness and allow some manipulation of the data, searching via xpath, or whatever. You could use this to create HTML from RSS feeds, format data retrieved from a web service, or whatever you can think of. Keep in mind that doing XML transformations can require a lot of resources depending on the size of your XML document, so don’t push a 500 MB XML document to the client in order to let it do the transformations. Keep it lightweight, user friendly, and provide accessibility alternatives for people with older browsers.

One Response to “Client-side XML transformations with Sarissa”

  1. BJ Says:

    This is perfect for my Student Loan/Mesothelioma spam blog. Just kidding, awesome write-up, I’ll have to check this out. Great way to keep active content active without heavy server processing on crappy webhosts (like mine).

    heh heh

Leave a Reply

You must be logged in to post a comment.