XSLT: Transformation of a Large Source Document
This is a demonstration of transforming a large, messy source document. The source is huge and has a lot of information I'm not interested in. The transform will filter out the elements I want and organize them. I used an external stylesheet to format the results in a neat and simple layout.
The source is user collection data from boardgamegeek.com using the BGG XML API2. I've used the huge collection of a friend with permission. The source has everything needed to include a thumbnail image and link each game back to BGG. I'll use the 'status' element's 'own' and 'wanttoplay' attributes to filter out just the elements I want to display.
Show collection.xml - A cleaned up single element from the 2000+ line source.
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<?xml-stylesheet type="text/xsl" href="collection.xsl" ?>
<items totalitems="371" termsofuse="http://boardgamegeek.com/xmlapi/termsofuse"
pubdate="Sun, 07 Sep 2014 03:31:18 +0000">
<item objecttype="thing" objectid="27708" subtype="boardgame" collid="10831785">
<name sortindex="1">1960: The Making of the President</name>
<yearpublished>2007</yearpublished>
<image>http://cf.geekdo-images.com/images/pic215664.jpg</image>
<thumbnail>http://cf.geekdo-images.com/images/pic215664_t.jpg</thumbnail>
<status own="1" prevowned="0" fortrade="0" want="0"
wanttoplay="1" wanttobuy="0" wishlist="0" preordered="0"
lastmodified="2014-08-30 10:12:18" />
<numplays>2</numplays>
</item>
</items>
Show collection.xsl - The HTML transformation.
<?xml version="1.0" ?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html" version="4.0" encoding="UTF-8" />
<!--
Author: Brian Manning
This is a demo of XLST transformation. This transformation will convert the source
xml document into styled html. The source is a collection document from the
boardgamegeek.com BGG XML API2. The transform will return only elements that
meet certain attribute conditions from the enormous source file.
-->
<!-- Root template begins here. Contains the html skeleton. Head, body, etc. -->
<xsl:template match="/">
<html>
<head>
<title>Brian Manning | XML Transform Demo</title>
<link href='../style/primary.css' rel='stylesheet' type='text/css' />
<link href='../style/bodyContent.css' rel='stylesheet' type='text/css' />
<link href='../style/collection.css' rel='stylesheet' type='text/css' />
<script src='../js/collapseCode.js'></script>
</head>
<body>
<section id='wrapper'>
<div id='columns' class='container'>
<article>
<div class='title'>
<h2>Games User Wants to Play but Does Not Own:</h2>
<a href='javascript:toggleCode("output1")'
id='output1Btn'
class='button'>Show</a>
</div>
<div id='output1' class='hidden'>
<!--
selecting items/item where the status element has an 'own' attribute with a
value of 0 and a 'wanttoplay' attribute with a value of 1. Brackets set apart
the conditional portion. This will select all items/item nodes that meet the
condition.
-->
<xsl:apply-templates select="items/item[.//status[@own='0' and @wanttoplay='1']]">
</xsl:apply-templates>
</div>
<div class='title'>
<h2>Games User Wants to Play and Owns:</h2>
<a href='javascript:toggleCode("output2")'
id='output2Btn'
class='button'>Show</a>
</div>
<div id='output2' class='hidden'>
<!-- same thing as above here except now we're testing 'own' for a value of 1 -->
<xsl:apply-templates select="items/item[.//status[@own='1' and @wanttoplay='1']]">
</xsl:apply-templates>
</div>
</article>
</div>
</section>
</body>
</html>
</xsl:template>
<!--
This is the template that will fill in the values we want for each item.
-->
<xsl:template match="items/item">
<div class='game'>
<!--
Need to use attribute value templates for the img src due to the nested quotes.
Attribute value templates evaluate the expression in the curly braces and converts
the result to a string
-->
<img class='gameImage' src='{thumbnail}'></img>
<!--
Need to do something similar here. We want to append the item elements objectid
attribute to the end of the url. An attribute value template converts the value
to a string in the correct position for a link.
-->
<h2><a href='http://www.boardgamegeek.com/boardgame/{@objectid}' target='_blank'>
<xsl:value-of select="name"/></a></h2>
<span class='gameSub'>Published:
<xsl:value-of select="yearpublished"/>
| Number of Plays:
<xsl:value-of select="numplays"/>
</span>
</div>
</xsl:template>
</xsl:stylesheet>