With the help of EXSLT, it's possible to define your own functions in XSLT and use them throughout your stylesheets. I just discovered that recently, and it saved me a lot of repetitive typing in one of our projects. I can now just call my own function instead of <xsl:call-template name="foobar"><xsl:param>... all over the place. And functions can also be used in attributes, xsl:if elements and other places, where the call-template approach is really too awkward or just not applicable.
EXSLT is partly supported by libxslt (the one PHP uses) and other XSLT processors, therefore it's kind of portable, even if it's not an official W3C standard. EXSLT support is compiled in by default in libxslt nowadays. Most importantly for us now is that libxslt supports the functions extension of EXSLT.
Your selfdefined functions should have its own namespace, so we have to declare it in the template. Furthermore, we also have to declare the functions-extension namespace. And as with any extension namespace, with have to declare them in the extension-element-prefixes attribute:
Defining the function
The actual definition of a function works quite similar to a template definition. In our example, we just implement a max() functions, which returns the bigger value (quite useless case, since there's a EXSLT max() function, but easy to implement). Furthermore the second parameter is optional. If it's not declared, it will be 0.
The major difference to an xsl:template is the func:result, which works like return in your usual language. And the order of xsl:param specifies the order of the arguments in the function-call
Calling the function
You can call now your selfdefined function like any other XSLT-function. For example:
which should return 3210
Details and more examples can be found at http://www.exslt.org/func/index.html
There are also a lot more EXSLT functions, which can be quite useful from time to time.
Calling PHP Functions
If you're using XSLT with PHP5, then you can also call any PHP functions from within XSLT. See http://blog.bitflux.ch/p1582.html and http://blog.bitflux.ch/p1641.html and http://php5.bitflux.org/phpconf2004/slide_95.php for details.