Hiding XSLT Tag Soup

The ever-interesting Jeff Atwood correctly points out that many frameworks force you to create tag soup – a horrible mess of executable code and HTML markup. Commenters suggest a number of solutions but none are really satisfying.

Our in-house framework started back in the bad old days with Java emitting HTML directly – surely the worst of all worlds. We figured out early on that it was better to create XML first, and transform with XSLT; for instance, this reduced the pain of generating reports from our screens, since we can transform the XML to flat files and PDFs.

However, even XSLT can be pretty soupy:

  <xsl:when test="@current">
    <b><xsl:value-of select="@number"/></b>
    <span style="cursor: hand;">
      <xsl:attribute name="onClick">
        <xsl:value-of select="@number"/>
      <u><xsl:value-of select="@number"/></u>

This implements page numbers with links to all but the current page, similar to Google’s Goooooooooogle:
1 2 3 4
Not only do we have lots of XSLT logic with smatterings of HTML thrown in, we even have some inline JavaScript at lines 8-10, which is code inside markup inside code!

We could clean up this particular example but it’s way too easy to create a mess like this. So we’ve gradually introduced more and more generic templates that take XML of a certain form and produce the corresponding HTML – including all the messy bits like JavaScript. For instance, here’s how we render a table of data with headings, column selection, and sorting:

<xsl:call-template name="chunk-multiple">
  <xsl:with-param name="node" select="data/content/section/dataset[@name='TABLE']"/>

Yes, it’s cheating because the template code is still tasty tag gumbo. But we have only a few templates, and we can concentrate on making them as readable as possible with comments and careful layout, while each individual application screen is defined in just one language – XSLT.

There’s a lot more cleaning up we could do with templates for our buttons and forms, but at least it’s more broth than chowder. Bon app├ętit!