Superseded by XSLT 2.0 RELAX NG Grammar, 07 Apr 2005.

Validating XSLT 2.0

Volume 7, Issue 132; 25 Jul 2004; last modified 08 Oct 2010

A RELAX NG Grammar for XSLT 2.0 and the marvelous simplicity of externalRef.

As XSLT 2.0 matures, and with Michael Kay’s excellent processor (from Saxonica) available to start putting it through it’s paces in practice, I’ve been writing more and more XSLT 2.0 stylesheets.

I’ve been doing it in emacs, of course, with nxml mode. That ships with an XSLT 1.0 grammar and I’ve just been ignoring the apparent “errors” in 2.0 stylesheets.

Until yesterday, that is. Yesterday, I got fed up with my editor’s failure to detect as attributes in the wrong place and I went ahead and constructed an XSLT 2.0 grammar.

James got his grammar for 1.0 by running some XSLT over the grammar description in the spec. Not having that stylesheet handy, I just did it by hand. If you find any errors, let me know and I’ll fix them.

Having a grammar for 2.0 is nice (a usable grammar, I mean, the W3C XML Schema version in the spec doesn’t do me any good), but it raises a new problem: how do I get emacs to use the 2.0 grammar for 2.0 stylesheets and the 1.0 grammar for 1.0 stylesheets?

The short answer is: there isn’t any way (it could be done, but not with any of the techniques provided by an unmodified nxml mode). What I really needed was a stylesheet for either version of XSLT.

As I pondered how this might be done, how I might reconstruct the various patterns to account for whether or not they were descended from a xsl:stylesheet element with a version attribute of “1.0” or “2.0”, I remembered “externalRef”, a RELAX NG feature I hadn’t really needed before.

You want to see how easy it is to build a RELAX NG grammar that will validate either XSLT 1.0 or XSLT 2.0 stylesheets? It’s just this simple:

xslt10 = external "xslt10.rnc"
xslt20 = external "xslt20.rnc"
start = xslt10 | xslt20

How sweet is that? For your convenience, I’ve put that schema and a copy of James’ original online too.

I should point out that this doesn’t automatically handle mixtures of XSLT 1.0 and XSLT 2.0 elements in the same stylesheet. But it does validate entire stylesheets one way or the other.


Hi Norm,

I like the externalRef feature too. I actually would have liked to see an analogous feature in XSLT 2.0 (xsl:call-transform or some such). It would let you use existing stylesheets wholesale, without worry about conflicting modes (especially the default one), variable names, etc. Alas, that wasn't the only fight I lost ;-)


—Posted by Evan Lenz on 27 Jul 2004 @ 05:53 UTC #

Yes, that would have been nice. I bet there are a lot of nice things we could have done if we hadn't gotten tangled in the W3C XML Schema type system. And we could have finished in 2002, too! :-)

—Posted by Norman Walsh on 27 Jul 2004 @ 03:20 UTC #

Thanks for this schema! The "start = xslt10 | xslt20" trick is really cool.

"how do I get emacs to use the 2.0 grammar for 2.0 stylesheets and the 1.0 grammar for 1.0 stylesheets?"

While I don't have entry-help in Vim, I installed your schema so that I can validate XSLT 2.0 documents from within Vim (and from the shell).

I added an entry to my language list, now I get:

$ cat 2_0_simple.xslt

<html xsl:version="2.0" xmlns:xsl="" xmlns="">

<head> <title>Expense Report Summary</title> </head>

<body> <p>Total Amount: <xsl:value-of select="expense-report/total"/></p> </body> </html>

$ xval 2_0_simple.xslt

[xval] validating 2_0_simple.xslt against


[xval] jing:

$ # changed the file

$ xval 2_0_simple.xslt


[xval] jing:


error: element "fvalue-of" from namespace "" not allowed in this context


(it would be great if you could allow backtalkers to enter preformatted code, eg via HTML pre or some Wiki style markup)

—Posted by Tobi on 31 Jul 2004 @ 08:45 UTC #

"how do I get emacs to use the 2.0 grammar for 2.0 stylesheets and the 1.0 grammar for 1.0 stylesheets?

The short answer is: there isn’t any way (it could be done, but not with any of the techniques provided by an unmodified nxml mode)."

Does that mean that

can't be used to associate the XSLT 1.0 RNG/RNC with XSLT 1.0 documents and the XSLT 2.0 RNG/RNC with XSLT 2.0 documents?

—Posted by Tobi on 31 Jul 2004 @ 09:19 UTC #


My question was not rhetoric :)

I'd really be interested in an answer.


—Posted by Tobi on 07 Aug 2004 @ 03:36 UTC #

I always have a hard time getting to the Yahoo Groups archives (I get infinite redirection), so I can't follow the link you posted, but I expect you're pointing to James' "locating rules" language.

As it stands today, you can't select a schema URI based on an attribute value on the root element (or even on the combination of namespace *and* the name of the root element).

That means there's no way for nxml-mode to tell the difference between XSLT 1.0 and XSLT 2.0. But James and I have exchanged some email on the topic and I think there will be a new version that will be able to cope with the selection.

—Posted by Norman Walsh on 08 Aug 2004 @ 05:11 UTC #

Thanks for the reply!

Here's what I use:

Works great.

—Posted by Tobi on 08 Aug 2004 @ 07:49 UTC #

Is there a good debugger for XSLT 2.0?

—Posted by Marian on 08 Dec 2004 @ 10:05 UTC #

In my site-lisp\nxml-mode\schema directory I renamed James' original xslt.rnc to xslt10.rnc and installed Norm's xslt.rnc. I visited docbook.xsl and got the message, File mode specification error: (error "Reference not in a grammar at position 2 in c:/Program Files/emacs-21.3/site-lisp/nxml-mode/schema/xslt.rnc") in the echo area. The mode line indicates (nXML Valid). What am I doing wrong?

—Posted by Sean on 23 Dec 2004 @ 06:04 UTC #