The solutions to the XSLT exercises

Solution to exercise 1a:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output encoding="iso-8859-1" version="1.0"/>
  <xsl:template match="CollectionOfPoems">
    <html>
      <body><h1>Collection of poems</h1> 
        <xsl:apply-templates/>
      </body>
    </html>
  </xsl:template>
  <xsl:template match="Author">
    <br/>
    <h4>
      <xsl:apply-templates/>
    </h4>
  </xsl:template>
  <xsl:template match="FirstName">
    <xsl:apply-templates/>
    <xsl:text> </xsl:text>
  </xsl:template>
  <xsl:template match="LastName">
    <xsl:apply-templates/>
  </xsl:template>
  <xsl:template match="Title">
    <h2>
      <xsl:apply-templates/>
    </h2>
  </xsl:template>
  <xsl:template match="Strophe">
    <p>
      <xsl:apply-templates/>
    </p>
  </xsl:template>
  <xsl:template match="Verse">
    <xsl:apply-templates/>
    <br/>
  </xsl:template>
  <xsl:template match="Poem">
    <xsl:apply-templates/>
  </xsl:template>
  <xsl:template match="Bold">
    <b>
      <xsl:apply-templates/>
    </b>
  </xsl:template>
  <xsl:template match="Subtitle">
    <h4>
      <xsl:apply-templates/>
    </h4>
  </xsl:template>
</xsl:stylesheet>

Solution to exercise 1b:

With the help of the <xsl:apply-templates> element, further templates are searched for matching sub-elements. If no template is found, the content (text) is copied.

Solution to exercise 1c:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output encoding="iso-8859-1" version="1.0"/>
  <xsl:template match="CollectionOfPoems">
    <html>
      <body><h1>Collection of poems</h1> 
        <xsl:apply-templates/>
      </body>
    </html>
  </xsl:template>
  <xsl:template match="Author">
    <br/>
    <h4><!-- YourFirsName YourLastName --></h4>
  </xsl:template>
  <xsl:template match="FirstName">
    <xsl:apply-templates/>
    <xsl:text> </xsl:text>
  </xsl:template>
  <xsl:template match="LastName">
    <xsl:apply-templates/>
  </xsl:template>
  <xsl:template match="Title">
    <h2>
      <xsl:apply-templates/>
    </h2>
  </xsl:template>
  <xsl:template match="Strophe">
    <p>
      <xsl:apply-templates/>
    </p>
  </xsl:template>
  <xsl:template match="Verse">
    <xsl:apply-templates/>
    <br/>
  </xsl:template>
  <xsl:template match="Poem">
    <xsl:apply-templates/>
  </xsl:template>
  <xsl:template match="Bold">
    <b>
      <xsl:apply-templates/>
    </b>
  </xsl:template>
  <xsl:template match="Subtitle">
    <h4>
      <xsl:apply-templates/>
    </h4>
  </xsl:template>
</xsl:stylesheet>

Solution to exercise 2a:

The select attribute was supplemented in order to select only a particular part of the tree. All the other sub-elements are ignored in this way.

Solution to exercise 2b:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output encoding="iso-8859-1" version="1.0"/>
  <xsl:template match="CollectionOfPoems">
    <html>
      <body>
        <h1>Collection of poems</h1>
        <p>
          <xsl:call-template name="Title"/>
          <xsl:call-template name="Name"/>
        </p>
      </body>
    </html>
  </xsl:template>
  <xsl:template name="Title">
    <br/>
Titel: <xsl:apply-templates select="Poem/Title"/>
  </xsl:template>
  <xsl:template match="Title">
    <h4>
      <xsl:apply-templates/>
    </h4>
  </xsl:template>
  <xsl:template name="Name">
    <br/>
Author: <xsl:apply-templates select="Poem/Author/FirstName | Poem/Author/LastName"/>
  </xsl:template>
  <xsl:template match="Title">
    <h4>
      <xsl:apply-templates/>
    </h4>
  </xsl:template>
  <xsl:template match="FirstName">
    <br/>
    <xsl:apply-templates/>
    <xsl:text> </xsl:text>
  </xsl:template>
  <xsl:template match="LastName">
    <xsl:apply-templates/>
  </xsl:template>
</xsl:stylesheet>

Solution to exercise 2c:

Elements which are not listed in the list of the selected elements are not taken over into the target document.

Solution to exercise 3:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output encoding="iso-8859-1" version="1.0"/>
  <xsl:template match="CollectionOfPoems">
    <html>
      <body>
        <xsl:apply-templates/>
      </body>
    </html>
  </xsl:template>
  <xsl:template match="Author">
    <br/>
    <h4>
      <xsl:apply-templates/>
    </h4>
  </xsl:template>
  <xsl:template match="FirstName">
    <xsl:apply-templates/>
    <xsl:text> </xsl:text>
  </xsl:template>
  <xsl:template match="LastName">
    <xsl:apply-templates/>
  </xsl:template>
  <xsl:template match="Title">
    <h2>
      <xsl:apply-templates/>
    </h2>
  </xsl:template>
  <xsl:template match="Strophe">
    <p>
      <xsl:apply-templates/>
    </p>
  </xsl:template>
  <xsl:template match="Verse">
    <xsl:apply-templates/>
    <br/>
  </xsl:template>
  <xsl:template match="Poem">
  Year of publication: 
    <xsl:value-of select="@YearOfPublication"/>
    <br/><xsl:apply-templates/>
  </xsl:template>
</xsl:stylesheet>

Solution to exercise 4:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output encoding="iso-8859-1" version="1.0"/>
  <xsl:template match="CollectionOfPoems">
    <html>
      <body>
        <xsl:apply-templates/>
      </body>
    </html>
  </xsl:template>
  <xsl:template match="Author">
    <br/>
    <h4>
      <xsl:apply-templates/>
    </h4>
  </xsl:template>
  <xsl:template match="FirstName">
    <xsl:apply-templates/>
    <xsl:text> </xsl:text>
  </xsl:template>
  <xsl:template match="LastName">
    <xsl:apply-templates/>
  </xsl:template>
  <xsl:template match="Title">
    <h2>
      <xsl:apply-templates/>
    </h2>
  </xsl:template>
  <xsl:template match="Strophe">
    <p>
      <xsl:apply-templates/>
    </p>
  </xsl:template>
  <xsl:template match="Verse">
    <xsl:apply-templates/>
    <br/>
  </xsl:template>
  <xsl:template match="Poem">
    <br/>
    <xsl:if test="@Language='el'">The Poem is in Greek.
    <xsl:apply-templates/>
    </xsl:if>
  </xsl:template>
</xsl:stylesheet>

Solution to exercise 5a:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output encoding="iso-8859-1" version="1.0"/>
  <xsl:template match="/">
    <xsl:for-each select="//Poem">
      <xsl:sort order="ascending" data-type="number" select="@YearOfPublication"/>
      <xsl:sort order="ascending" data-type="text" select="Author/LastName"/>
      <xsl:apply-templates/>
    </xsl:for-each>
  </xsl:template>
  <xsl:template match="Author">
    <br/>
    <h4>
      <xsl:apply-templates/>
    </h4>
  </xsl:template>
  <xsl:template match="FirstName">
    <xsl:apply-templates/>
    <xsl:text> </xsl:text>
  </xsl:template>
  <xsl:template match="LastName">
    <xsl:apply-templates/>
  </xsl:template>
  <xsl:template match="Title">
    <h2>
        <xsl:apply-templates/>
    </h2>
    <p>Year of publication: <xsl:value-of select="parent::Poem/@YearOfPublication"/></p>
  </xsl:template>
  <xsl:template match="Strophe">
    <p>
      <xsl:apply-templates/>
    </p>
  </xsl:template>
  <xsl:template match="Verse">
    <xsl:apply-templates/>
    <br/>
  </xsl:template>
  <xsl:template match="Poem">
    <xsl:apply-templates/>
  </xsl:template>
</xsl:stylesheet>
Browser view of the solution to exercise 5a (excerpt):

Browser view: solution 5a

Solution to exercise 5b:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output encoding="iso-8859-1" version="1.0"/>
  <xsl:template match="/">
    <h1>Table Of Contents</h1>
    <p>
      <xsl:for-each select="//Poem">
        <xsl:sort order="ascending" data-type="number" select="@YearOfPublication"/>
        <xsl:sort order="ascending" data-type="text" select="Author/LastName"/>
        <a href="#{Title}">
          <xsl:value-of select="Title"/>
        </a><br/>
      </xsl:for-each>
    </p>
    <xsl:for-each select="//Poem">
      <xsl:sort order="ascending" data-type="number" select="@YearOfPublication"/>
      <xsl:sort order="ascending" data-type="text" select="Author/LastName"/>
      <xsl:apply-templates/>
    </xsl:for-each>
  </xsl:template>
  <xsl:template match="Author">
    <br/>
    <h4>
      <xsl:apply-templates/>
    </h4>
  </xsl:template>
  <xsl:template match="FirstName">
    <xsl:apply-templates/>
    <xsl:text> </xsl:text>
  </xsl:template>
  <xsl:template match="LastName">
    <xsl:apply-templates/>
  </xsl:template>
  <xsl:template match="Title">
    <h2>
      <a name="{.}"/>
      <xsl:apply-templates/>
    </h2>
    <p>Year of publication: <xsl:value-of select="parent::Poem/@YearOfPublication"/></p>
  </xsl:template>
  <xsl:template match="Strophe">
    <p>
      <xsl:apply-templates/>
    </p>
  </xsl:template>
  <xsl:template match="Verse">
    <xsl:apply-templates/>
    <br/>
  </xsl:template>
  <xsl:template match="Poem">
    <xsl:apply-templates/>
  </xsl:template>
</xsl:stylesheet>
Browser view to the solution of exercise 5b:

Browser view: solution 5b

Solution to exercise 6a:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output encoding="iso-8859-1" version="1.0"/>
  <xsl:template match="CollectionOfPoems">
    <html>
      <body>
        <xsl:apply-templates/>
      </body>
    </html>
  </xsl:template>
  <xsl:template match="Author">
    <br/>
    <h4>
      <xsl:apply-templates/>
    </h4>
  </xsl:template>
  <xsl:template match="FirstName">
    <xsl:apply-templates/>
    <xsl:text> </xsl:text>
  </xsl:template>
  <xsl:template match="LastName">
    <xsl:apply-templates/>
  </xsl:template>
  <xsl:template match="Title">
    <h2>
      <xsl:number format="I" level="any"/>
      <xsl:text> </xsl:text>
      <xsl:apply-templates/>
    </h2>
  </xsl:template>
  <xsl:template match="Strophe">
    <p>
      <b>Strophe <xsl:number/>
      </b>
      <br/>
      <xsl:apply-templates/>
    </p>
  </xsl:template>
  <xsl:template match="Verse">
    <b>Verse <xsl:number level="multiple" count="//Poem | //Poem/Strophe | //Poem/Strophe/Verse" format="I.1.1"/></b>
    <br/>
    <xsl:apply-templates/>
    <br/>
  </xsl:template>
  <xsl:template match="Poem">
    <br/>
    <xsl:apply-templates/>
  </xsl:template>
</xsl:stylesheet>
Browser view to the solution of exercise 6a:

Browser view: solution 6a

Solution to exercise 6b:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output encoding="iso-8859-1" version="1.0"/>
  <xsl:template match="CollectionOfPoems">
    <html>
      <body>
        <xsl:apply-templates/>
      </body>
    </html>
  </xsl:template>
  <xsl:template match="Author">
    <br/>
    <table>
      <col width="30px"/>
      <tbody>
        <tr>
          <td style="color:#G9G9G9; font-size:9pt">
            <xsl:number count="//Title | //Verse | //Author | //Subtitle" format="1" level="any"/>
          </td>
          <td style="font-size:12pt; font-weight:bold">
            <xsl:apply-templates/>
          </td>
        </tr>
      </tbody>
    </table>
  </xsl:template>
  <xsl:template match="FirstName">
    <xsl:apply-templates/>
    <xsl:text> </xsl:text>
  </xsl:template>
  <xsl:template match="LastName">
    <xsl:apply-templates/>
  </xsl:template>
  <xsl:template match="Title">
    <table>
      <col width="30px"/>
      <tbody>
        <tr>
          <td style="color:#G9G9G9; font-size:9pt">
            <xsl:number count="//Title | //Verse | //Author | //Subtitle" format="1" level="any"/>
          </td>
          <td style="font-size:18pt; font-weight:bold">
            <xsl:apply-templates/>
          </td>
        </tr>
      </tbody>
    </table>
  </xsl:template>
  <xsl:template match="Subtitle">
    <table>
      <col width="30px"/>
      <tbody>
        <tr>
          <td style="color:#G9G9G9; font-size:9pt">
            <xsl:number count="//Title | //Verse | //Author | //Subtitle" format="1" level="any"/>
          </td>
          <td style="font-size:14pt; font-weight:bold">
            <xsl:apply-templates/>
          </td>
        </tr>
      </tbody>
    </table>
  </xsl:template>
  <xsl:template match="Strophe">
    <p>
      <xsl:apply-templates/>
    </p>
  </xsl:template>
  <xsl:template match="Verse">
    <table>
      <col width="30px"/>
      <tbody>
        <tr>
          <td style="color:#G9G9G9; font-size:9pt">
            <xsl:number count="//Title | //Verse | //Author | //Subtitle" format="1" level="any"/>
          </td>
          <td style="font-size:10pt">
            <xsl:apply-templates/>
          </td>
        </tr>
      </tbody>
    </table>
  </xsl:template>
  <xsl:template match="Poem">
    <br/>
    <xsl:apply-templates/>
  </xsl:template>
</xsl:stylesheet>
Browser view to the solution of exercise 6b:

Browser view: solution 6b

Solution to exercise 7:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output encoding="iso-8859-1" version="1.0"/>
  <xsl:template match="CollectionOfPoems">
    <html>
      <body>
        <xsl:apply-templates/>
      </body>
    </html>
  </xsl:template>
  <xsl:template match="Author">
    <br/>
    <h4>
      <xsl:apply-templates/>
    </h4>
  </xsl:template>
  <xsl:template match="FirstName">
    <xsl:apply-templates/>
    <xsl:text> </xsl:text>
  </xsl:template>
  <xsl:template match="LastName">
    <xsl:apply-templates/>
  </xsl:template>
  <xsl:template match="Title">
    <h2>
      <xsl:apply-templates/>
    </h2>
  </xsl:template>
  <xsl:template match="Strophe">
    <p>
      <xsl:apply-templates/>
    </p>
  </xsl:template>
  <xsl:template match="Verse">
    <xsl:apply-templates/>
    <br/>
  </xsl:template>
  <xsl:template match="Poem">
    <xsl:variable name="Year">
      <xsl:value-of select="starts-with(@YearOfPublication,'-')"/>
    </xsl:variable>
    <div>
      <xsl:if test="$Year='true'">
        <xsl:attribute name="style">background-color:red</xsl:attribute>
      </xsl:if>
      <br/>
      <xsl:apply-templates/>
    </div>
  </xsl:template>
</xsl:stylesheet>
Browser view to the solution of exercise 7 (excerpt):

Browser view: solution 7

Solution to exercise 8a:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:import href="Solution8b.xslt"/>  
  <xsl:output encoding="iso-8859-1" version="1.0"/>
  <xsl:template match="CollectionOfPoems">
    <html>
      <body>
        <xsl:apply-templates/>
      </body>
    </html>
  </xsl:template>
</xsl:stylesheet>

Solution to exercise 8b:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output encoding="iso-8859-1" version="1.0"/>

  <xsl:template match="Author">
    <br/>
    <h4>
      <xsl:apply-templates/>
    </h4>
  </xsl:template>
  <xsl:template match="FirstName">
    <xsl:apply-templates/>
    <xsl:text> </xsl:text>
  </xsl:template>
  <xsl:template match="LastName">
    <xsl:apply-templates/>
  </xsl:template>
  <xsl:template match="Title">
    <h2>
      <xsl:apply-templates/>
    </h2>
  </xsl:template>
  <xsl:template match="Strophe">
    <p>
      <xsl:apply-templates/>
    </p>
  </xsl:template>
  <xsl:template match="Verse">
    <xsl:apply-templates/>
    <br/>
  </xsl:template>
  <xsl:template match="Poem">
    <xsl:apply-templates/>
  </xsl:template>
</xsl:stylesheet>

Copyright © dpunkt.verlag GmbH 2004
Printing of the online version is permitted exclusively for private use. Otherwise this chapter from the book "XSL-FO in der Praxis" ("XSL-FO in practice") is subject to the same provisions as those applicable for the hardcover edition: The work including all its components is protected by copyright. All rights reserved, including reproduction, translation, microfilming as well as storage and processing in electronic systems.

dpunkt.verlag GmbH, Ringstraße 19B, 69115 Heidelberg, fon 06221-14830, fax 06221-148399, hallo@dpunkt.de