Re: [xsl] Avoiding boneheaded mistakes in XSLT?

Subject: Re: [xsl] Avoiding boneheaded mistakes in XSLT?
From: Michael Kay <mike@xxxxxxxxxxxx>
Date: Tue, 28 Dec 2010 23:13:01 +0000
On 28/12/2010 22:35, David Sewell wrote:
This is to some extent a general programming question, as it is possible
with any programming language to write something that is syntactically
legitimate (i.e., does not throw a compile- or run-time error) but fails
to produce expected results because of a mistake in logic or something
else. I'm sure we've all had the experience of beating our heads against
a programming failure that turns out to be the result of a very simple
(aka "boneheaded") mistake that seems obvious when found. It seems to me
that this is perhaps more likely with XSLT/XPath than some other
environments, because of (1) the general verbosity of expression, and
(2) the many complexities of return values when you're working with a
combination of XML documents and fragments, and sequences of nodes
and/or atomic values.
In general, verbosity equals redundancy, which should in principle *increase* the chance that a programming mistake results in an invalid program. So verbosity cannot be blamed for this effect.

I think the main reason for the problem is that an XSLT/XPath program makes many references to names (of elements and attributes) which do not have to be declared, so that using an incorrect name is not an error (either static or dynamic), but rather results in an XPath expression that simply selects nothing.

A good defence against this is to write schema-aware stylesheets. I fully admit that this involves a lot of up-front effort which can be hard to justify. But the larger the system you are writing, the more this investment will pay off.

These won't catch all your errors of course. Using xsl:copy-of when you meant xsl:value-of is akin to writing "plus" when you meant "minus", and no programming language is ever going to catch that kind of error.

Michael Kay
Over the last few days I've been working on some especially complex
transforms and have lost more time that I'd like owing to some of these
simple mistakes. Not the first time by a long shot I've made them, either. For

1. In an XPath expression, using "something/node" where I wanted
"something/node()" [ditto text vs. text()]: always means zero results and
can drive you crazy if you don't notice the missing parentheses;

2. Using xsl:copy-of instead of xsl:apply-templates in a case where
recursive processing is in fact needed on the item in question;

3. Using xsl:value-of when you really need xsl:copy-of for a variable
that is a sequence;

4. Bad logic with xsl:analyze-string, putting processing into
xsl:non-matching-substring that should have gone into
xsl:matching-substring or vice versa.

Do these sound familiar? Other favorite traps?

Has anyone come up with a useful list of "things to check any time my
code is not working the way it should"?


Current Thread