Eric Hartwell's InfoDabble

 
Welcome to Eric Hartwell's InfoDabble
About | Site Map
Home Tech Notes Apollo 17: Blue Marble Apollo 17 Flight Journal   Calendars About me  

Apollo Transcripts: XSL Formatting Transformations

By Eric Hartwell - last updated April 1, 2006

Given the XML data layout and the desired HTML output format,  designing the XSLT is fairly straightforward.

Required Space

XSLT drops spaces between tags, but does not support   Many sources recommend using   as a replacement, but MediaWiki rejects this. It turns out the HTML standard does not support ASCII characters higher than #FF.

For the time being, I rearranged the style sheet so that there is always a non-blank character adjacent to a required space.

Not allowed:  <b>Cernan:</b>&nbsp; <xsl:value-of select="node()" />
Workaround: <b>Cernan: </b><xsl:value-of select="node()" />

First Pass:

The first pass translates tags that will be rendered by wikitext, adds the transcript-specific style sheet, and wraps the remaining tags with XmlTransform instructions for the second pass.

Tag Attribute Action Output Format
/ (root)   Insert or append transcript's CSS styles
Wrap output with <XmlTransform xsl="xsl2"> ... </XmlTransform>
<XmlTransform xsl="xsl2">
....
<style type="text/css"> ... </style>
</XmlTransform>
section   Tag as ==Wikitext heading 2== </XmlTransform>
==value of chapter attribute: value of title attribute==
<XmlTransform xsl="xsl2">
  chapter (optional) Prefixed to title as Chapter: Title
  title Title of section
  seq (optional) Sequence and/or section number
include   Insert content from a wikitext page {{Wikitext template}} </XmlTransform>
{{value of title attribute}}
<XmlTransform xsl="xsl2">
  title Title of wikitext page to insert
Note: Should use a lookup table to convert the transcript's section title to the title of the corresponding wiki page.
event/include   Insert content from a wikitext page {{Wikitext template}} </event></XmlTransform>
{{value of title attribute}}
<XmlTransform xsl="xsl2"><event>
  title Title of wikitext page to insert
Future tags      
photo   Insert image from a wikitext page {{Wikitext template}} </event></XmlTransform>
(wikitext image reference)
<XmlTransform xsl="xsl2"><event>

The actual Apollo 17 first pass transcript XSL looks like this:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" />

<!-- Main transform with style sheet at end -->

<xsl:template match="/">
<xsl:text disable-output-escaping="yes">&lt;XmlTransform xslfile="C:/Domains/ehartwell.com/wwwroot/wiki/extensions/AS17Flight.xsl"&gt;</xsl:text>

<xsl:apply-templates />

<xsl:text disable-output-escaping="yes">&lt;style type="text/css"&gt;</xsl:text>
.met {font-family: Arial, Helvetica, sans-serif; font-size: 12px; color: black}
.def {font-family: Arial, Helvetica, sans-serif; font-size: 12px; color: black}
.pao {font-family: Arial, Helvetica, sans-serif; font-size: 12px; color: DarkGreen; margin-left:25px}
.ob {font-family: Arial, Helvetica, sans-serif; font-size: 12px; color: #660000; margin-left:25px}
.tec {font-family: Arial, Helvetica, sans-serif; font-size: 12px; color: black; margin-left:25px}
.ed {font-family: Arial, Helvetica, sans-serif; font-size: 12px; color: Blue; margin-left:50px}
.edinc {font-family: Arial, Helvetica, sans-serif; font-size: 12px; color: MediumBlue; margin-left:60px; margin-right:50px;}
.db {font-family: Arial, Helvetica, sans-serif; font-size: 12px; color: SaddleBrown; margin-left:50px}
.alt {font-family: Arial, Helvetica, sans-serif; font-size: 11px; color: DimGray; margin-left:40px; margin-top:-10px;}
.other {font-family: Arial, Helvetica, sans-serif; font-size: 12px; color: black; margin-left:25px}
.photo {font-family: Arial, Helvetica, sans-serif; font-size: 12px; color: red; margin-left:25px}
<xsl:text disable-output-escaping="yes">&lt;/style&gt;</xsl:text>
<xsl:text disable-output-escaping="yes">&lt;/XmlTransform&gt;</xsl:text>
</xsl:template>

<xsl:template match="XmlTransformInput">
<xsl:apply-templates />
</xsl:template>

<!-- Section titles -->

<xsl:template match="section">
<xsl:text disable-output-escaping="yes">&lt;/XmlTransform&gt;</xsl:text>
==<xsl:value-of select="@chapter" /><xsl:if test="@chapter">: </xsl:if><xsl:value-of select="@title" />==
<xsl:text disable-output-escaping="yes">&lt;XmlTransform xslfile="C:/Domains/ehartwell.com/wwwroot/wiki/extensions/AS17Flight.xsl"&gt;</xsl:text>
<xsl:apply-templates />
</xsl:template>

<!-- Include a wiki page: Root level and part of an event -->

<xsl:template match="/include">
<xsl:text disable-output-escaping="yes">&lt;/XmlTransform&gt;</xsl:text>
{{:<xsl:value-of select="@title" />}}
<xsl:text disable-output-escaping="yes">&lt;XmlTransform xslfile="C:/Domains/ehartwell.com/wwwroot/wiki/extensions/AS17Flight.xsl"&gt;</xsl:text>
</xsl:template>

<xsl:template match="event/include">
<xsl:text disable-output-escaping="yes">&lt;/event&gt;&lt;/XmlTransform&gt;</xsl:text>
<div class="edinc"><p><b>[[<xsl:value-of select="@title" />]]: </b>{{:<xsl:value-of select="@title" />}}</p></div>
<xsl:text disable-output-escaping="yes">&lt;XmlTransform xslfile="C:/Domains/ehartwell.com/wwwroot/wiki/extensions/AS17Flight.xsl"&gt;&lt;event&gt;</xsl:text>
</xsl:template>

<!-- Important! Preserve all XML tags that we don't explicitly process here -->

<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>

</xsl:stylesheet>

Second Pass:

The second pass processes the content tags that weren't handled in the first pass. Most of the HTML formatting is done here because the tags would have been stripped by the wikitext parser in the previous pass.

The actual Apollo 17 second pass transcript XSL looks like this:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" />

<xsl:template match="/">
<xsl:apply-templates />
</xsl:template>

<xsl:template match="section">
<xsl:apply-templates />
</xsl:template>
<xsl:template match="subsection">
<xsl:apply-templates />
</xsl:template>

<xsl:template match="event">
<p class="met"><b><xsl:value-of select="@met" /></b></p>
<xsl:apply-templates />
</xsl:template>

<xsl:template match="event/quote[@src='TechDebrief']">
<xsl:choose >
<xsl:when test = "@who='CDR'"><p class="db"><b>Cernan</b> (Technical Debriefing) <xsl:value-of select="node()" /></p></xsl:when>
<xsl:when test = "@who='CMP'"><p class="db"><b>Evans</b> (Technical Debriefing) <xsl:value-of select="node()" /></p></xsl:when>
<xsl:when test = "@who='LMP'"><p class="db"><b>Schmitt</b> (Technical Debriefing) <xsl:value-of select="node()" /></p></xsl:when>
<xsl:otherwise><p class="db"><b><xsl:value-of select="@who" /></b> (Technical Debriefing) <xsl:value-of select="node()" /></p></xsl:otherwise>
</xsl:choose>
</xsl:template>

<xsl:template match="event/quote[not(@src)]">
<xsl:choose >
<xsl:when test = "@who='CDR'"><p class="tec"><b>Cernan: </b><xsl:value-of select="node()" /></p></xsl:when>
<xsl:when test = "@who='CMP'"><p class="tec"><b>Evans: </b><xsl:value-of select="node()" /></p></xsl:when>
<xsl:when test = "@who='LMP'"><p class="tec"><b>Schmitt: </b><xsl:value-of select="node()" /></p></xsl:when>
<xsl:when test = "@who='CCo'"><p class="tec"><b>Obermeyer: </b><xsl:value-of select="node()" /></p></xsl:when>
<xsl:when test = "@who='CCp'"><p class="tec"><b>Parker: </b><xsl:value-of select="node()" /></p></xsl:when>
<xsl:when test = "@who='PAO'"><p class="pao"><b>Public Affairs Officer: </b><xsl:value-of select="node()" /></p></xsl:when>
<xsl:when test = "@who='LCC'"><p class="pao"><b>Launch Control: </b><xsl:value-of select="node()" /></p></xsl:when>
<xsl:otherwise><p class="other"><b><xsl:value-of select="@who" />: </b><xsl:value-of select="node()" /></p></xsl:otherwise>
</xsl:choose>
<xsl:apply-templates select="alternate" />
</xsl:template>

<xsl:template match="event/quote/alternate">
<p class="alt">
<xsl:choose >
<xsl:when test = "@src='PAO'">(PAO) </xsl:when>
<xsl:when test = "@src='Tech'">(Air-to-Ground) </xsl:when>
<xsl:otherwise>(Tape 17-<xsl:value-of select="@src" />) </xsl:otherwise>
</xsl:choose>
<xsl:value-of select="node()" /><br />
</p>
</xsl:template>

<xsl:template match="event/photo">
<p class="photo"><b>Photo <xsl:value-of select="@id" /></b>
<xsl:if test = "@frame"> (Frame <xsl:value-of select="@frame" />) </xsl:if>
<xsl:if test = "node()"> <b>:</b><xsl:value-of select="node()" /></xsl:if>
</p>
</xsl:template>

<xsl:template match="event/comment">
<p class="ed">[<xsl:value-of select="node()" />]</p>
</xsl:template>

<xsl:template match="style">
<style type="text/css"><xsl:value-of select="node()" /></style>
</xsl:template>

</xsl:stylesheet>


Revision History

  • April 1, 2006 - two-pass transform
  • March 27, 2006 - initial version
Creative Commons License

Unless otherwise noted, this work is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 3.0 License

 

Site Map | About Me