Archive

Archive for August 14th, 2002

XSLT, Perl, Haskell, and a word on language design

August 14th, 2002 No comments

An interesting thread over at kuro5hin on the tribulations one person had when writing a filter to convert XML documents to LaTeX using XSLT (with examples of how some of the transformations would be handled using Perl or Haskell instead).

My initial reaction when faced with problems such as the one described in this post (lots of highly repetitive code) is always to use a different language to generate the code – e.g. use Perl to generate the repetitive XSLT. Then if you want to add a new substitution, just add it in Perl, and generate the resulting XSLT.

I still think that I’ll probably end up going down that path for the Music Database (probably using Template::Toolkit to process the .xsl files when they’re requested), but first I’m going to see how far I can stretch the abstraction in XSLT itself.

In the story above, several people pointed out better approaches to the problem, which make the ‘correct way’ much more readable and maintainable. But it’s still not great.

XML, per se, is more verbose than I’d usually like to deal with, so I’m probably going to end up with some level of abstraction into this – but I don’t want to get there too early.

Tags:

Functional Programming with XSLT – A proof through examples

August 14th, 2002 No comments

This paper sets out to show that XSLT is a true functional language, by implementing 35 of the most common functions that you would encounter in such a language (foldl, map, minimum, sum, sumTree etc)! It’s long (the PDF version is 76 pages) – mostly because of the code: just because XSLT can implement all these things, that doesn’t mean it’s easy, simple, elegant or clean!

I’m enjoying playing with the new musicdatabase chain of CDDB data -> MySQL -> SQL -> Class::DBI -> FireCore -> Template::Toolkit -> XML -> XSLT -> HTML -> CSS -> display, but XSLT is jumping out as by far the most verbose, ugly, and unreadable link in that chain. It hasn’t been around enough yet, or been used widely enough yet, for there to be much written on on the speed/cost of development, or maintainability.

In theory, the really complex stuff should be sufficiently abstractable to allow for building up quite powerful libraries. Although XSLT doesn’t support higher order functions directly, it’s possible to simulate them, as this paper (and its examples) shows. If this sort of thing can be turned into a “sufficiently encapsulated hack”, then it may indeed be possible to write XSLT relatively quickly and neatly.

Tags:

XSLT Abstraction

August 14th, 2002 No comments

I’m trying to learn how to abstract common elements of XSLT away. For example, the MusicDatabase’s shiny new XML output gives the run-length of a CD, or a track on it, in seconds. But, for output, we’d really like to show it as minutes and seconds (i.e. 308 would become 5:08).

This is fairly simple to do:

  <xsl:value-of select="format-number(runlength div 60, '#')"/>:
  <xsl:value-of select="format-number(runlength mod 60, '00')"/>

However, I don’t want to have to repeat that everywhere, a) because I’m lazy and don’t want to have to go to the effort of finding the file it’s in every time I want it, and cutting and pasting from there, and b) because I worked that out myself on my second day of playing seriously with XSLT, and I’ll probably discover later that there’s a much better way, or that it doesn’t cope properly with some fringe case, and I won’t want to have to go through and change it everywhere it’s used (see Laziness above). Oh, and c) because it’s always good practice to do this sort of stuff, for lots of reasons that never seemed as convincing as laziness.

Initial research into this persuaded me that there were two main approaches: parameterisation (see Creating Generic XSLT Transforms), or named templates (see The Tao of Recursion: Named Templates in XSLT, or Math and XSLT [with its 'Calculate pi using Leibnitz recursive named template']).

Named templates seemed the best way to go, so I added a secs_to_mins template:

  <xsl:template name="secs_to_mins">
    <xsl:param name="secs" />
    <xsl:value-of select="format-number($secs div 60, '#')" />:
    <xsl:value-of select="format-number($secs mod 60, '00')" />
  </xsl:template>

And then called it:

  <xsl:call-template name="secs_to_mins">
    <xsl:with-param name="secs" select="runlength"/>
  </xsl:call-template>

(It didn’t work at first, as I’d left the $ signs off, but it everything was fine once I realised that).

Then all I had to do was move it into its own file, and place at the top of any XSL file that wants it:

  <xsl:import href="lib/secs_to_mins.xsl" />

Wahey! Now I can build lots of nice components to play with.

Now I just need to find a good way to play with XSLTunit or equivalent to build up a test suite for these…

Tags: