[XSL-LIST Mailing List Archive Home] [By Thread] [By Date]

[xsl] Some Pointers on XSLT 2.0 vs. 1.0 and for Using XSLT 2.0 on the Web


Subject: [xsl] Some Pointers on XSLT 2.0 vs. 1.0 and for Using XSLT 2.0 on the Web
From: "Jesse Heines" <heines@xxxxxxxxxx>
Date: Mon, 13 Oct 2008 13:55:48 -0400

I have been using XSLT 1.0 for many years to render Java Server Pages on my
website (http://teaching.cs.uml.edu/~heines) from data stored in XML files.
Due to the emergence of a new project, a graduate student and I decided to
try to upgrade my website to XSLT 2.0.  We installed saxon9.jar in the
website's WEB-XML/lib directory, restarted the Jakarta-Tomcat server, and of
course some things broke.  That is, certain pages wouldn't render due to
XSLT errors.

After a few days (on and off) of tests and research, we were delighted to be
able to get everything working again.  I share here some of the things we
learned for the benefit of others who may be considering doing the same.

The basic issue is that XSLT 2.0 and XPath 2.0 appear to be a bit more
strict than XSLT 1.0.  This has a number of ramifications.

(1)  Some of my XSL code inadvertently contained \ as a "file separator"
(using the Java term) in file paths.  This was not a problem on Windows, of
course, where paths use backslashes, but it caused Saxon errors on Linux,
which was of course expecting /.  It seems that XSLT 1.0 "forgave" the error
on Linux and must have the translated \ in paths to / because I never got an
error before, but XSLT 2.0 is not as forgiving.  Note that the / works just
as well as \ on Windows, which is true in Java code as well.

(2)  Another problem was that my XSL code contained calls to the XPath
concat() function with just one argument.  Such calls were used to render
HTML code that would otherwise not be well-formed.  Here's an example:

    <!-- set color if specified -->
    <xsl:if test="date/@color">
      <xsl:value-of select="concat( '&lt;font color=&quot;#8B0000&quot;&gt;'
)"
                    disable-output-escaping="yes" />
    </xsl:if>
  
      ... do some fancy XSLT stuff here ...

    <!-- close color tag if specified -->
    <xsl:if test="date/@color">
      <xsl:value-of select="concat( '&lt;', '/font', '&gt;' )"
                    disable-output-escaping="yes" />
    </xsl:if>

Note: The following will *not* work because the XSL would not be well-formed
and therefore the stylesheet would not compile:

    <xsl:if test="date/@color">
      <font color="#8B0000">
    </xsl:if>
      ... do some fancy XSLT stuff here ...
    <xsl:if test="date/@color">
      </font>
    </xsl:if>

The 1-agrument concat() function call worked fine in XSLT 1.0, but XSLT 2.0
generated the error:

    Error at xsl:value-of on line 146 column 59 of common-lecs.xsl:
      XPST0017: XPath syntax error at char 34 on line 146 in {...at( '<font
color="#B0000">...}:
        Function concat() must have at least 2 arguments

In retrospect, it would have been better to code the 1-argument call using
the XPath string() function:

    <xsl:value-of select="string( '&lt;font color=&quot;#8B0000&quot;&gt;'
)"
                  disable-output-escaping="yes" />

This is what I changed the 1-argument concat() function call to, thus
solving the problem in XSLT 2.0.

(3)  Another error that XSLT 1.0 forgave and XSLT 2.0 did not is that I
inadvertently put a test attribute on an xsl:choose element.  That was
obviously a mistake, but I never caught it because XSLT 1.0 didn't complain.
The more strict XSLT 2.0, however, wouldn't compile the stylesheet.

(4)  When working on the web, problems with an XSLT stylesheet cause the web
page to display something like:

     javax.xml.transform.TransformerConfigurationException: 
     Failed to compile stylesheet. 6 errors detected.  

This is not very helpful to developers because there is no indication as to
where the errors are.  As it turns out, the full error messages are written
to the stdout_YYYYMMDD.log file in the Tomcat logs directory.  One always
has access to that directory on a Windows system, but on Linux, one may not.


Therefore, to find out what the errors really are, one can run the
saxon9.jar file like this:

     C:\ > java -jar saxon9.jar {path}\461-lecs.xml {path}\common-lecs.xsl
     Warning: at xsl:stylesheet on line 12 column 80 of common-lecs.xsl:
       Running an XSLT 1.0 stylesheet with an XSLT 2.0 processor
     Error at xsl:value-of on line 106 column 59 of common-lecs.xsl:
       XPST0017: XPath syntax error at char 34 on line 106 in {...at( '<font
color="#B0000">...}:
         Function concat() must have at least 2 arguments
     Error at xsl:value-of on line 146 column 59 of common-lecs.xsl:
       XPST0017: XPath syntax error at char 34 on line 146 in {...at( '<font
color="#B0000">...}:
         Function concat() must have at least 2 arguments
     Error at xsl:choose on line 321 column 39 of common-lecs.xsl:
       XTSE0090: Attribute @test is not allowed on element <xsl:choose>
     Error at xsl:value-of on line 325 column 55 of common-lecs.xsl:
       XPST0017: XPath syntax error at char 34 on line 325 in {...at( '<font
color="#B0000">...}:
         Function concat() must have at least 2 arguments
     Error at xsl:value-of on line 330 column 55 of common-lecs.xsl:
       XPST0017: XPath syntax error at char 34 on line 330 in {...at( '<font
color="#09900">...}:
         Function concat() must have at least 2 arguments
     Error at xsl:value-of on line 338 column 51 of common-lecs.xsl:
       XPST0017: XPath syntax error at char 19 on line 338 in {concat(
'</font>' )}:
         Function concat() must have at least 2 arguments
     Failed to compile stylesheet. 6 errors detected.

Voila!  Now it is relatively straightforward to correct one's errors.

(5)  One last small thing about what you see above.  When using XSLT 1.0
stylesheets with saxon9.jar on the web, the warning shown above:

     Warning: at xsl:stylesheet on line 12 column 80 of common-lecs.xsl:
       Running an XSLT 1.0 stylesheet with an XSLT 2.0 processor

does not show up on the web page, so I didn't have to go through and change
all the xsl:stylesheet declarations on my website:

     <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">

This would have been a tedious job, as there are over 150 XSL stylesheets on
my website and I have a healthy fear making global changes on multiple
files.

The bottom line for readers who would like to upgrade to XSLT 2.0 but have
an understandable fear that their websites or applications will no longer
work is that our experience is that XSLT 2.0 appears to be fully backward
compatible with XSLT 1.0 except for a few more restrictive rules.  It took
us a few days to get things working, but the newer capabilities of XSLT 2.0
-- particularly the grouping constructs -- are well worth the effort.

Jesse

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Jesse M. Heines, Ed.D.
Assoc. Prof. & Undergraduate Coordinator
Dept. of Computer Science
University of Massachusetts Lowell
mailto:heines@xxxxxxxxxx
http://teaching.cs.uml.edu/~heines


Current Thread
Keywords