Macros for XSLT

Gary King is confused because [XSLT] seems so ridiculously verbose. Others have already suggested mad higher-order function tricks using XSLT 2.0.

My solution: Macros. If XSLT lacks an element to do what you want (creating a text node with a newline, in Gary's case), just invent the feature you need and send your XSLT stylesheet through another XSLT stylesheet to implement it.


Say you have demo.xsl which wants to use

to emit a newline. (In this example, `x' is simply the namespace for our extensions.) Write an additional stylesheet macros.xsl and send the original demo.xsl through the macro stylesheet to generate the actual XSLT source code. A macro template for <x:br> would be as simple as:
  <xsl:template match="x:br">
In the macro stylesheet, xsl is the namespace of the "macro definition" and _xsl is the namespace of the "macro expansion". (If you care about details, the trick is to use xsl:namespace-alias to make the XSLT processor believe they are different namespaces.)


For a more interesting example of macro use, suppose we want to repeat our code count times. Doing this kind of iteration involves a recursive template call, which we want to hide. We will define a macro <x:dotimes> that can be used like this:
  <x:dotimes var="i" count="3">
    <xsl:value-of select="$i"/>
Our macro stylesheet replaces each use of <x:dotimes> with a template call, and adds a recursive template as a top-level element:
  <xsl:template match="xsl:stylesheet">
      <xsl:apply-templates select="@*|node()"/>
      <xsl:for-each select="//x:dotimes">
        <_xsl:template name="x:dotimes_{generate-id()}">
          ... recursive template definition here ...
  <xsl:template match="x:dotimes">
    <_xsl:call-template name="x:dotimes_{generate-id()}">
      ... parameters elided for brevity ...
Download the full macros.xsl and demo.xsl to try the example. To run it with xsltproc, use the Makefile in the same directory.


There's exactly one way to do it

XOM is a DOM alternative written in Java and for Java -- in contrast to DOM, which feels wrong in almost every language.

Key phrases:
  • "Comatose lists"
  • This is a cathedral, not a bazaar
  • There's exactly one way to do it
  • The Wrong Side of 80/20

Lots of good ideas waiting to be stolen. Stay tuned for a Common Lisp adaptation.