Home & blog  /  Tag: Webkit  /

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

Bizarre webkit bug with 'typeof'

posted: 01 Mar '11 08:28 tags: Javascript, Webkit, browser, bug, REGEXP

That'll teach me to post scripts and assume, without checking, that the normally-reliable Chrome and Safari will play ball. The other day I posted my JS simulation of REGEXP lookbehinds, but Marcus Tucker found it didn't work in these browsers.

After some digging, it seems there's a bizarre bug in Webkit browsers (i.e. Chrome and Safari) whereby regular expression objects are considered functions, not objects. So:

alert(typeof /\w+/);

Opera, IE and FF all say 'object', as you'd expect, but Chrome and Safari say 'function'. Very odd. I fixed the issue by using instanceof rather than typeof:

1alert(/\w+/ instanceof RegExp)

2//all browsers say true - happy days!

post a comment