Home & blog  /  2011  /  Oct  /

Annoyances with client-side XSL transformation

posted: 25 Oct '11 19:37 tags: XML, XSL, webkit, import, browser, Opera

A current project of mine heavily involves XSL.

XSL is that rare thing: a technology that can run both on the client and on the server.This might be exciting if it wasn't so dubious; the likelihood of browsers and servers implementing a recommendation in equivalent fashion, just seems so unlikely.

That said, XSL does, I must admit, enjoy a pretty decent implementation in the browser, and with few cross-browser issues, too.

Naturally you won't want to be trying it in the likes of IE6 (which runs a very, very stripped-down version of XSL) but if you don't care about IE6, you should be fine.

Today, though, I did hit a snag: where XSL imports are concerned. Specifically, they don't work in Webkit browsers (Safari, Chrome).

This is only a problem when transforming your XSL through Javascript, i.e. within a webpage context - not if you're opening up the XML manually. In the latter case, your imports will work fine.

This is annoying, and it's not at all clear why Google/Apple don't add support for this.

Weirdness in Opera

As anyone close to me will tell you (or, rather, sigh and then tell you), my browser of choice is Opera. Now Opera does support XSL includes in the context of JS transformation... in a way.

If you load the XSL from a file, any XSL include statements within it will work.

1//utility function to load XML file and return as XML object

2function loadXMLDoc(dname) {

3     if (window.XMLHttpRequest)

4         xhttp=new XMLHttpRequest();

5     else

6         xhttp=new ActiveXObject("Microsoft.XMLHTTP");

7     xhttp.open("GET",dname,false);

8     xhttp.send("");

9     return xhttp.responseXML;

10}

11    

12//load and parse XML & XSL files

13var xml = loadXMLDoc('some_xml_file.xml');

14var xsl = loadXMLDoc('some_xsl_file.xsl');

15    

16//non-IE

17if (document.implementation && document.implementation.createDocument) {

18     xsltProcessor=new XSLTProcessor();

19     xsltProcessor.importStylesheet(xsl);

20     var output = xsltProcessor.transformToFragment(xml, document);

21//IE

22} else if (window.ActiveXObject)

23     var output = xml.transformNode(xsl);

24return output;

If, however, you specify and convert your XSL from a string, not from a file, you can forget about XSL includes.

1//prepare XML & XSL strings then parse into XML objects

2var xml = "1.0" encoding="ISO-8859-1"?>";

3var xsl = "1.0" encoding="ISO-8859-1"?>1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">xsl:template>";

4xml = $.parseXML(xml);

5xsl = $.parseXML(xsl);

This would appear to be a bug. In both cases, the resultant xml and xsl vars are both typeof == 'XML Document Object'. In other words, they should be equivalent - but only the former approach allows XSL includes.

Looks like I'll be doing my XSL on the server after all.

post a comment

XML Tree - visualise and traverse your XML

posted: 18 Oct '11 21:49 tags: XML, tree, traversal, node

XMLTree, just posted in the scripts section, is a utility for visualising and traversing XML in tree format.

You point it to an XML file, or manually feed it XML, and it does the rest, turning your nodes into a traversable tree.

But it's more than that; you can stipulate callbacks to fire when a node is expanded/collapsed and/or clicked. Callbacks are passed certain standard arguments, such as a reference to the node that was clicked and the XPath to it.

Behold! I even made a lovely demo for you involving Nintendo characters:

You can also deep-link to a point or points within the tree, so that, on load, the tree opens at a specific point or points. By extension, this means the tree is refresh-friendly, i.e. it won't forget which nodes were open when you reload the page.

Head over here to download, get usage info or view a demo.

1 comments | post new
older posts >