How to do things right in XSLT

23 Sep 07 0 comments

The last few weeks we transfered our hosted sites to a new Server, that meant we also had to switch to the new XSLTProc, some (or a lot) of the “old” XSLT-Files made problems, because they were build upon Bugs of the old XSLTProc.

I wrote a little script which gets the XSLT and XML from the old Server and processes it with my new local installed XSLT processors. I manly use Xalan to validate the XSLT-files, because XSLT is more tolerant then XSLTProc.

I wrote down the most common problems to inspect them and to prevent that i make the same crap. :)

Defining the Doctype

All the old XSLT-Files defined the Doctype with <xsl:text/> in the following way:

<xsl:text disable-output-escaping="yes">
&lt;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"&gt;
</xsl:text>

The right way to define the Doctype in an XSLT-File is to define it in the <xsl:output/> and to define the XML-Namespace in <xsl:stylesheet>:


<xsl:stylesheet version="1.0" 
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
        xmlns:html="http://www.w3.org/1999/xhtml" 
        xmlns="http://www.w3.org/1999/xhtml" 
                exclude-result-prefixes="html" 
>
....
<xsl:output method="xml" 
        doctype-system="http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd" 
    doctype-public="-//W3C//DTD XHTML 1.0 Transitional//EN" 
    encoding="utf-8" indent="yes" 
    omit-xml-declaration="yes" />

It was not possible to switch to the right way, in most cases.

XSLTProc acts different when the output method is set to “xml” and no Doctype is given in the xsl:output, it is not giving you valid XHTML, it gives you valid XML, which can lead to problems in the Browser and the HTML-Validator.

I recommend to define the Doctype in the xsl:output!

Definition of template parameters and variables

Like in programming languages you can define variables, like in programming languages they are available in a specified area. If you define the variable as a child of xsl:stylesheet you can call them in the whole xsl:stylesheet, if you define it in a xsl:template you can just call it in that xsl:template.

Unlike programming languages you are not able to overwrite them. In the old XSLT-Files variables were defined twice or more times in one xsl:template, this is not valid. Also parameters are kind of a variable, and can not be overwritten.

This was #1 on the list “Which Problems make me insane”, followed by:

Unused xsl:templates

Most of the variable overwrite tries were in those unused xsl:templates, and there were a lot of them.
Really try to avoid them. if you really don’t need them, remove them!

(I hope i find time to publish the script which helped me a lot by just grep for call-templates af a template, currently it is just useful for me)

Wrong use of CDATA

Also a very common problem was that JavaScript code in a <script>-Element were wrong escaped, the old XSLTProc didn’t touch the code in a CDATA section, the new one does, and this is the valid way, because a CDATA in XSLT means don’t treat the following piece of code as XSL, not don’t touch this. So in the new XSLTProc < were escaped to &lt;

The way you should JS in XSLT (if you really need to) is:

<script language="JavaScript" type="text/javascript">
<xsl:text disable-output-escaping="yes">
/* &lt;![CDATA[ */
<![CDATA[
function Bla(){
 alert('Hello World')
}
]]>
/* ]]&gt; */
</xsl:text>
</script>

tags:

Post your comment