I was thinking earlier about the difference between named
tamplates and functions in xslt 2.0 and have not found satisfactory criterion for a decision of what to use in each case. I was not first one who has
troubled with this, see
stylesheet functions or named templates.
To feel easy I deliberately have decided to use functions
whenever possible, avoid named tamplates completely, and use matching templates
to apply logic depending on context (something like virtual function). I've forgot about the issue until yesterday. To realize the
difference one should stop thinking of it, quite opposite she must start solving
practical xslt tasks, and if there is any difference, except syntactic, it will
manifest itself somehow.
To make things obvious to those whose programming roots are in a language like C++ I shall compare
xsl:function with free standing (or static) C++ function, and named xsl:template with C++ member function. In C++ you can use both free standing and member
functions interchangeably, however if there is only one argument (among others)
whose state transition this function represents then it's preferrable to define
it as a member function. The most important difference between these two type of
functions is that a member function has hidden argument "this", and is able to
access its private state.
Please, do not try to think I'm going to compare template context item in xslt 2.0 with "this" in C++,
quite opposite I consider context item as a part of a state. I'm arguing
however, of private state that can be passed through template call chain with tunnel parameters. Think of
a call tunneling some state (like options, flags, values), and that state accessed several levels deep in call hierarchy, whenever one needs to. You cannot do it with xsl:function, you cannot pass all private state through the function call, you just do not know of it.
This way my answer to the tacit question is:
- use xsl:function to perform independent unit of logic;
- use named xsl:template when a functionality is achieved cooperatively, and when you will possibly need to share the state between different implementation blocks;
After thinking through this, I've noticed that such distinction does not exist in XQuery 1.0.
There is no tunneling there.