wizzwizz4
wizzwizz4

Reputation: 6426

XSLT variable scope with import

I'm building an incredibly ambitious and almost certainly doomed client-side CMS (using XSLT 1.0, which is supported by most browsers). As part of it, I'd like to have template.xsl to be a stylesheet, and have the business logic be included from config.xsl.

Here's the sort of XML file I have:

<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet href="/XRCS/xrcs/template.xsl" type="text/xsl"?>
<xrcs:page id="/"
           xmlns="http://www.w3.org/1999/xhtml"
           xmlns:xrcs="xrcs:xrcs">
    <xrcs:title>XRCS Home Page</xrcs:title>
    <xrcs:content>
        Hello I am some HTML!
        <p>
            Paragraphs!
        </p>
        <h2>Headings!</h2>
        <p>
            More paragraphs!
        </p>
    </xrcs:content>
</xrcs:page>

To start with, I wanted the page title to be customisable from config.xsl. I thought that this would be pretty simple:

Of course, I now know that $xrcs-url is almost useless, since imports are evaluated before variables. However, Firefox complains with some unspecified error when attempting to use this stylesheet.

This stylesheet (where I've replaced the import with a variable definition), on the other hand, works fine:

Why?!

The only explanation I've come up with so far is that the variables are file-specific. If that's the case, I shall be very, very annoyed, but I suppose I could define yet another schema for a configuration to live in, and use that $xrcs-url variable after all...

Is my assumption correct? Are these variables file-specific? I've found no documentation on it, and the XSLT spec is a W3 spec (difficult to read unless you already have a very good understanding of it already) so there's no help there.

Upvotes: 1

Views: 1256

Answers (2)

wizzwizz4
wizzwizz4

Reputation: 6426

<xsl:import /> has to occur before any other child element of <xsl:stylesheet />. That was the direct cause of the error I was getting.

I'm accepting Michael Kay's answer because it actually says this, even though I missed it and have spent a few days trying to figure it out myself!

Upvotes: 0

Michael Kay
Michael Kay

Reputation: 163468

The scope of global (top-level) variables, as well as other named declarations such as named templates, is the whole stylesheet, that is, all modules. When module A imports module B, then both modules can declare a variable V, and the declaration of V in A is used everywhere, including in B (in the language of the spec, A has higher import precedence).

If you're trying to write something ambitious in XSLT then I would recommend persevering with understanding the spec. Or you might prefer my book XSLT Programmers Reference from Wrox/Wiley - but it covers XSLT 2.0 rather than 1.0, unless you can find an older edition.

I'm having trouble understanding what you mean by "Of course, I now know that $xrcs-url is almost useless, since imports are evaluated before variables." Imports are not "evaluated", they are declarations used to construct the stylesheet at compile time. I don't know what you want to use $xrcs-url for (your code appears to make no attempt to use it), it seems perfectly usable in principle, though perhaps not what you intended it for (but I don't know what you intended it for, of course).

Incidentally there is one stylesheet here with two modules: it helps to get the terminology right.

Then you say: "However, Firefox complains with some unspecified error when attempting to use this stylesheet." Well, it's probably complaining that the xsl:import declarations are in the wrong place. But more to the point, running XSLT code in the browser is not a good approach for development and testing. The diagnostics are lousy. It's much more productive (you say you're being ambitious) to use a specialized IDE such as oXygen.

Upvotes: 2

Related Questions