Mithi's little XSLT tinkering

... or "what is this XML file the DVD Profiler spits out for anyway?"

A word of warning up-front: I haven't learned XSL systematically (yet) but had a good look at David Smith's XSL (see below) and changed that file gradually to fit my desires. For absolute beginners of HTML and programming this page might be unsuitable.


The online-list belonging to DVD Profiler has some disadvantages, e.g. you can't do a genre sort or anything like that. The Profiler however offers an option to export the database in XML format, and I make use of that for building my own DVD lists.


Highly simplified XML and XSLT behave similarly to HTML and CSS. The first supplies the content, the latter the layout. To transform XML to something nice it has to be parsed, which can take place at 3 different places:


Simply type
xsltproc.exe ungesehen-collection.xsl collection.xml > ungesehen-collection.html
msxsl.exe collection.xml ungesehen-collection.xsl > ungesehen-collection.html
java -jar saxon9he.jar -novw collection.xml ungesehen-collection.xsl > ungesehen-collection.html
press enter and your finished. What? That was a bit too fast? Okay, I'll try to explain the XSLT a little bit:

<?xml version="1.0" encoding="ISO-8859-1"?>
<!-- ***************
     Programmed by David Smith 4 Mar 2003
     changed by Michael 'Mithi' Cordes 02.04.2006
     *************** -->
Which XML-Version do we use, and which Encoding for this XSL.
And some commentaries.
<xsl:stylesheet xmlns:xsl="" version="1.0">
  <xsl:include href="templates/template-genres.xsl"/>
  <xsl:include href="templates/template-regions.xsl"/>
  <xsl:include href="templates/template-credits.xsl"/>
This loads the templates.
<xsl:output method="html"
  doctype-public="-//W3C//DTD HTML 4.01 Transitional//EN"
This defines that a HTML-file should be produced, to be more specific a HTML 4.01.
<xsl:template match="Collection">
So, here the fun starts, the first XSL:Template. It triggers on everything within <Collection>, which means the complete XML-File.
    <title>Mithis ungesehene DVDs</title>
    <meta name="author" content="Michael Cordes"/>
    <link rel="stylesheet" type="text/css" href="/privat/layout.css"/>
    <link rel="stylesheet" type="text/css" href="/privat/dvd-list.css"/>
    <meta http-equiv="content-type" content="text/html; charset=iso-8859-1"/>
    <link rel="shortcut icon" href="/privat/favicon.ico" type="image/x-icon"/>
          <h1>Mithis ungesehene DVDs</h1>
    <table class="box" cellpadding="0" summary="DVD Liste" align="center">
The usual HTML-Code for the Webpage that should be created. Small peculiarity: tags must always have a closing-tag, single tags like <br> have to have a slash at the end. The created HTML-code will look as usual.
        <xsl:apply-templates select="DVD"> 
        <xsl:sort select="RunningTime" data-type="number"/>
Now it gets exciting. The template <DVD> is invoked. The results that this template gives back will be sorted, in this case according to the running time.
Again, simple HTML, the lower part of the page.
And here the fun is over, the end of the whole shebang.
<xsl:template match="DVD">
<!-- Ungesehen Owned -->
  <xsl:if test="not(contains(Events, 'Watched')) and contains(CollectionType, 'Owned')">
This searches in all <DVD>-entries if the DVD is in my 'owned'-list but hasn't a 'Watched' entry.
         <td class="dvdTitle" colspan="2"><xsl:value-of select="Title"/>
           <xsl:if test="count(Description)>0">
             <br/><xsl:value-of select="Description"/>
         <td colspan="2">
           <table border="0" width="100%">
If the criteria are matched the <Title> and if present the <Description> are taken.
               <td colspan="2" class="dvdData">
               <xsl:apply-templates select="Credits"/></td> 
The imported template "Credits" is invoked.
               <td width="50%" class="dvdData">
               <xsl:value-of select="RunningTime"/><xsl:text> min</xsl:text></td>
               <td class="dvdData"><xsl:apply-templates select="Regions"/></td>
               <td class="dvdData" colspan="2"><xsl:apply-templates select="Genres"/></td>
This includes the RunningTime and like with Credits the Regions and Genres.
As soon as no more records match the IF inquiry it jumps back.
<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet xmlns:xsl="" version="1.0">
<xsl:template match="Credits">
All <Credits> of the current <DVD> are searched.
  <xsl:if test="count(Credit[CreditSubtype = 'Director'])>0">
    <xsl:if test="count(Credit[CreditSubtype = 'Director'])>1">
    <xsl:text>: </xsl:text>
Here the decison is made whether it's 'Director' or 'Directors'.
    <xsl:for-each select="Credit[CreditSubtype = 'Director']">
    <xsl:if test="position() <= 3">
      <xsl:value-of select="FirstName"/>
      <xsl:text> </xsl:text>
      <xsl:value-of select="LastName"/>
      <xsl:if test="not (position()=last())">
        <xsl:text>, </xsl:text>
    <xsl:if test="count(Credit[CreditSubtype = 'Director'])>3">
And here the firstnames and surname of the first 3 Directors are taken. If there are more than 3 Directors a succinct 'others' will represent the rest.
The End, and again the jump back.

Change to David Smith's XSL

Apart from the obvious differences in the layout of the produced HTML file I made only few substantial changes:


Last updated: 08. September 2012

back to my Homepage (german)