Skip to content

Instantly share code, notes, and snippets.

@vicmortelmans
Created January 27, 2011 08:53
Show Gist options
  • Save vicmortelmans/798257 to your computer and use it in GitHub Desktop.
Save vicmortelmans/798257 to your computer and use it in GitHub Desktop.
XML data + XSL stylesheet for browser + CSS in single file (useful for DMS publishing), including vertical table headers with wrapped text as bonus
<?xml-stylesheet type="text/xsl" href="#"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<!-- the main concept of this file is obtained from
http://stackoverflow.com/questions/360628/embed-xsl-into-an-xml-file -->
<xsl:output omit-xml-declaration="yes"/>
<xsl:key name="reviewers" match="reviewer" use="."/>
<!-- browsers have XSLT 1.0, so 'for-each-group' must be implemented
using traditional Muenchian grouping -->
<xsl:variable name="vEmbDoc">
<!-- the variable is just an xsl-friendly container for the
source xml data to be available in the same file as the
xsl logic. The variable as such is not used -->
<reviewers>
<!-- top-level reviewers apply to all projects -->
<reviewer role="RA">John Doe</reviewer>
<reviewer role="R">Barack Obama</reviewer>
<reviewer role="RA">Adam Smith</reviewer>
<reviewer role="R">King George</reviewer>
<reviewer role="RA">Robert Franck</reviewer>
<project name="CR Mammo 1C">
<reviewer role="RA">Julie Robertson</reviewer>
<reviewer role="RA">Vic Donder</reviewer>
<reviewer role="RA">Ladi Di</reviewer>
</project>
<project name="CR Mammo 1B">
<reviewer role="RA">Julie Robertson</reviewer>
<reviewer role="RA">Dimitri Hofman</reviewer>
<reviewer role="RA">Paul Paulus</reviewer>
<reviewer role="RA">Ladi Di</reviewer>
</project>
<project name="CR 35-X">
<reviewer role="RA">Julie Robertson</reviewer>
<reviewer role="RA">Vic Donder</reviewer>
<reviewer role="RA">Ladi Di</reviewer>
</project>
</reviewers>
</xsl:variable>
<xsl:template match="reviewers">
<html>
<head>
<title>IOM Reviewers</title>
<style>
<!-- in principle the css-data should be enclosed by xml
comments. This can be generated by <xsl:comment>,
but Firefox doesn't see the css-data that way -->
DIV.vertical
{
<!-- the vertical style is obtained from
http://scottgale.com/blog/css-vertical-text/2010/03/01/ -->
writing-mode: tb-rl;
-webkit-transform: rotate(-90deg);
-moz-transform: rotate(-90deg);
-o-transform: rotate(-90deg);
white-space: nowrap;
display: block;
bottom: 0;
width: 40px;
height: 40px;
}
TD.cell
{
text-align: center;
}
TD
{
padding: 4px;
border-right: 1px solid #B7B7B7;
}
TR.alternate0
{
background-color: #EACACA;
}
TABLE
{
border-collapse: collapse;
}
TD.vertical
<!-- improvement to vertical style for use as column headers -->
{
height: 200px;
<!-- modify this value to control height of the header row.
This should be synchronized with the max-length wrapping
parameter (see below) -->
vertical-align: bottom;
border-top: 1px solid #B7B7B7;
}
</style>
<!--link rel="stylesheet" type="text/css" href="IOM_Reviewers.css" /-->
</head>
<body>
<table>
<tr>
<td/>
<xsl:apply-templates select="project" mode="headerrow-cell"/>
</tr>
<xsl:apply-templates select="reviewer|project/reviewer[generate-id(.)=generate-id(key('reviewers',.))]" mode="row"/>
</table>
</body>
</html>
</xsl:template>
<xsl:template match="project" mode="headerrow-cell">
<td class="vertical headerrow-cell">
<div class="vertical">
<xsl:call-template name="wrap">
<xsl:with-param name="string" select="@name"/>
</xsl:call-template>
</div>
</td>
</xsl:template>
<xsl:template match="reviewer" mode="row">
<tr class="alternate{position() mod 2}">
<td class="headercolumn-cell">
<xsl:value-of select="."/>
</td>
<xsl:apply-templates select="ancestor::reviewers/project" mode="column">
<xsl:with-param name="reviewer" select="."/>
</xsl:apply-templates>
</tr>
</xsl:template>
<xsl:template match="project" mode="column">
<xsl:param name="reviewer"/>
<td class="cell">
<xsl:variable name="project-reviewer">
<xsl:value-of select="reviewer[.=$reviewer]/@role"/>
<xsl:value-of select="ancestor::reviewers/reviewer[.=$reviewer]/@role"/>
</xsl:variable>
<xsl:if test="$project-reviewer">
<xsl:value-of select="$project-reviewer"/>
</xsl:if>
</td>
</xsl:template>
<xsl:template name="wrap">
<xsl:param name="string"/>
<xsl:param name="used" select="0"/>
<xsl:variable name="max-length" select="25"/>
<!-- This variable should be synchronized with the height of the
header row; see the CSS above -->
<xsl:message><xsl:value-of select="$string"/> <xsl:value-of select="$used"/></xsl:message>
<xsl:choose>
<xsl:when test="string-length($string) + number($used) &lt; number($max-length)">
<xsl:value-of select="$string"/>
</xsl:when>
<xsl:otherwise>
<xsl:variable name="first-word" select="substring-before($string,' ')"/>
<xsl:variable name="now-used">
<xsl:choose>
<xsl:when test="string-length($first-word) + number($used) + 1 &gt; number($max-length)">
<xsl:text>0</xsl:text>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="string-length($first-word) + number($used) + 1"/>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:if test="$now-used = 0">
<br/>
</xsl:if>
<xsl:value-of select="$first-word"/>
<xsl:text> </xsl:text>
<xsl:call-template name="wrap">
<xsl:with-param name="string" select="substring-after($string,' ')"/>
<xsl:with-param name="used" select="$now-used"/>
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template match="xsl:template"/>
</xsl:stylesheet>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment