tags:

views:

219

answers:

2

I'm creating a template which produces output based on a single string, passed via parameter, and does not use an input XML document. xsltproc seems to happily run with a single parameter specifying the stylesheet, but I don't see a way to trigger a template without an input file (no parameter to xsltproc to run a named template, for example).

I'd like to be able to run:

xsltproc --stringparam bar baz foo.xsl

But I'm currently having to run, with the "main" template matching "/":

echo '<xml/>' | xsltproc --stringparam bar baz foo.xsl -

How can I get this to work? I'm sure I've seen other templates in the past which were meant to be run without an input document, but I don't remember how they worked or where to find them again. :-)

+1  A: 

In general, you cannot do this with XSLT - specification requires there to be an input document, and for the processing to start with applying any available templates to its root node. Some XSLT processors might give a way to do what you want (e.g. execute a named template) as an extension, but I don't know any such, and it doesn't seem that xsltproc is one of them, judging from its man page.

In fact, this sounds pretty dubious in general, as the purpose of using XSLT to produce some output from a plain string input is unclear - it's not the kind of task it's generally good at.

Pavel Minaev
+1 - if there's not even a root node, there can't be anything for call-template or apply-templates to match on.
Meredith L. Patterson
Technically, a named template doesn't have to "match" anything, so it could be done. And in XSLT 2.0 it would even be possible to have a template run with no current context node (if you do `xsl:call-template` from within an `xsl:function`).
Pavel Minaev
It's a strange set of requirements I've been given. I've just told them they'll have to be happy with option #2 in my original post. :-)
Ben Blank
+2  A: 

Actually, this has been done quite often.

In XSLT 2.0 it is defined in the Spec. that providing an initial context node is optional. If no initial context node is provided (no source XML document), then it is important to provide the name of a named template which is to be executed as the entry point to the transformation.

In XSLT 1.0 one can provide to the transformation its own primary stylesheet module (file) as the source XML document, and of course, the transformation can completely ignore this source XML document. This technique has long ago been demonstrated and used by Jeni Tennison.

For example:

<?xml-stylesheet type="text/xsl" href="example.xml"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"&gt;
    <xsl:template match="/">
      <p>Hello, world!</p>
    </xsl:template>
</xsl:stylesheet>

When the above code is saved in a file named "example.xml" and then the folder contents is displayed with Windows Explorer, double-clicking on the file "example.xml" will open IE and produce:

Hello, world!

Dimitre Novatchev
For XSLT 1.0, I assume that would involve using `document('')`? I've poked around on Jeni's site, but wasn't able to find an example of this and the seemingly-obvious solution (including `document()` a template's `match=` attribute) gives me errors in both libxslt and Xalan-J. Do you have a direct link to an example?
Ben Blank
@ben-blank I have updated the answer and it now includes a working example. If you just save the XSLT stylesheet as described, then double-clicking it within the Windows Explorer will cause the transformation to be performed and the result to be displayed by IE.Certainly, no separate input file was used, and in fact the stylesheet itself was used as the input file.Jeni had the practice of using this technique.
Dimitre Novatchev
Works! Didn't even need to change the extension to "xml". (Well, for `xsltproc`, anyway — I didn't try with IE.)
Ben Blank