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>