I've hacked on a little bit about XSLT and I think it's about time I added some more. So this post will serve as the next instalment, and somewhat of an introduction to the uninitiated.
Lets say we were to consider the following data:
As XML, it could concievably arrive like this:
<raceResults><finish result="1" jockey="Y. Iwata" originISO="JPN">Delta Blues</finish><finish result="2" jockey="D. Oliver" originISO="JPN">Pop Rock</finish><finish result="3" jockey="C. Munce" originISO="AUS">Maybe Better</finish><finish result="4" jockey="G. Boss" originISO="AUS">Zipping</finish><finish result="5" jockey="J. Egan" originISO="GB">Land 'n Stars</finish><finish result="6" jockey="C. Brown" originISO="AUS">Mahtoum</finish><finish result="7" jockey="K. Fallon" originISO="IRE">Yeats</finish><finish result="8" jockey="M. Rodd" originISO="NZ">Activation</finish><finish result="9" jockey="C. Williams" originISO="NZ">Mandela</finish><finish result="10" jockey="S. Seamer" originISO="GB">Glistening</finish></raceResults>
And that is fine, and may well even be useful. The place where we should introduce XSLT is when we would like to do something with it like turning that XML into text, HTML, or more XML.
Text is an easy one to start with. Consider the following stylesheet:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0"><xsl:output method="text"/>
<xsl:template match="/"> <xsl:apply-templates select="raceResults"/></xsl:template>
<xsl:template match="raceResults">position,jockey,horse,<xsl:apply-templates select="finish"/></xsl:template>
<xsl:template match="finish"> <xsl:value-of select="@result"/>,<xsl:value-of select="@jockey"/>,<xsl:value-of select="."/>,</xsl:template>
</xsl:stylesheet>
When applied to our XML, it will produce the following result:
position,jockey,horse,1,Y. Iwata,Delta Blues,2,D. Oliver,Pop Rock,3,C. Munce,Maybe Better,4,G. Boss,Zipping,5,J. Egan,Land 'n Stars,6,C. Brown,Mahtoum,7,K. Fallon,Yeats,8,M. Rodd,Activation,9,C. Williams,Mandela,10,S. Seamer,Glistening,
The trick is first to not look for flow control in the traditional fashion (For loops, etc). Instead the XSLT processor will treat it in the following manner:
And that is it!
Now did you notice how literal text was handled? All the bits of your output can live inside the template. Now if we wanted an HTML representation we would use the following template:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0"><xsl:output method="html"/>
<xsl:template match="/"> <html><head><title>Race Results</title></head><body> <xsl:apply-templates select="raceResults"/> </body></html></xsl:template>
<xsl:template match="raceResults"><xsl:apply-templates select="finish"/></xsl:template>
<xsl:template match="finish"> <p>Position <b><xsl:value-of select="@result"/></b>was <b><xsl:value-of select="."/></b>ridden by <b><xsl:value-of select="@jockey"/></b></p></xsl:template>
...and following exactly the same steps as the text example, the XSLT processor will output the following HTML:
Position 1 was Delta Blues ridden by Y. Iwata
Position 2 was Pop Rock ridden by D. Oliver
Position 3 was Maybe Better ridden by C. Munce
Position 4 was Zipping ridden by G. Boss
Position 5 was Land 'n Stars ridden by J. Egan
Position 6 was Mahtoum ridden by C. Brown
Position 7 was Yeats ridden by K. Fallon
Position 8 was Activation ridden by M. Rodd
Position 9 was Mandela ridden by C. Williams
Position 10 was Glistening ridden by S. Seamer
As you can imagine, it can be easy to get a stylesheet for HTML output that contains a lot of HTML markup! The important thing to note in this example is that the HTML inside the stylesheet must be valid XML as well as valid HTML. Note the closing </p> which would normally be optional in HTML is manditory here.
Now we get to the fun example: Turning XML into XML :D
Why would we want to turn XML into XML? For as many reasons as you have XML in your life! Imagine turning the above document into its own RSS feed for example.
We could use the following template:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0"><xsl:output method="xml" indent="yes"/>
<xsl:template match="/">
<rss version="2.0"> <channel> <title>Race News</title> <link>http://www.horses.com/</link> <description>Live race results as they cross the finish line.</description> <language>en-us</language> <pubDate>Tue, 13 Nov 2006 17:45:00 AEST</pubDate> <lastBuildDate>Tue, 13 Nov 2006 17:45:00 AEST</lastBuildDate> <docs>http://blogs.law.harvard.edu/tech/rss</docs> <generator>My RSS transformation</generator> <managingEditor>james@deepdark.net</managingEditor> <webMaster>james@deepdark.net</webMaster> <xsl:apply-templates select="raceResults"/> </channel></rss>
</xsl:template>
<xsl:template match="finish"> <item> <title><xsl:value-of select="."/></title> <link>http://www.horses.com/lookup?<xsl:value-of select="."/></link> <description>Registered in: <xsl:value-of select="@originISO"/> . Ridden by: <xsl:value-of select="@jockey"/></description> <pubDate>Tue, 13 Nov 2006 17:45:00 AEST</pubDate> <guid>http://www.horses.com/results/race6273-<xsl:value-of select="@result"/></guid> </item></xsl:template></xsl:stylesheet>
This example is the reason I took you so far down the page. It builds on the key points of the prior two examples:
The output is the following lovely RSS feed:
<?xml version="1.0"?><rss version="2.0"><channel><title>Race News</title><link>http://www.horses.com/</link><description>Live race results as they cross the finish line.</description><language>en-us</language><pubDate>Tue, 13 Nov 2006 17:45:00 AEST</pubDate><lastBuildDate>Tue, 13 Nov 2006 17:45:00 AEST</lastBuildDate><docs>http://blogs.law.harvard.edu/tech/rss</docs><generator>My RSS transformation</generator><managingEditor>james@deepdark.net</managingEditor><webMaster>james@deepdark.net</webMaster><item><title>Delta Blues</title><link>http://www.horses.com/lookup?Delta Blues</link><description>Registered in: JPN . Ridden by: Y. Iwata</description><pubDate>Tue, 13 Nov 2006 17:45:00 AEST</pubDate><guid>http://www.horses.com/results/race6273-1</guid></item><item><title>Pop Rock</title><link>http://www.horses.com/lookup?Pop Rock</link><description>Registered in: JPN . Ridden by: D. Oliver</description><pubDate>Tue, 13 Nov 2006 17:45:00 AEST</pubDate><guid>http://www.horses.com/results/race6273-2</guid></item><item><title>Maybe Better</title><link>http://www.horses.com/lookup?Maybe Better</link><description>Registered in: AUS . Ridden by: C. Munce</description><pubDate>Tue, 13 Nov 2006 17:45:00 AEST</pubDate><guid>http://www.horses.com/results/race6273-3</guid></item><item><title>Zipping</title><link>http://www.horses.com/lookup?Zipping</link><description>Registered in: AUS . Ridden by: G. Boss</description><pubDate>Tue, 13 Nov 2006 17:45:00 AEST</pubDate><guid>http://www.horses.com/results/race6273-4</guid></item><item><title>Land 'n Stars</title><link>http://www.horses.com/lookup?Land 'n Stars</link><description>Registered in: GB . Ridden by: J. Egan</description><pubDate>Tue, 13 Nov 2006 17:45:00 AEST</pubDate><guid>http://www.horses.com/results/race6273-5</guid></item><item><title>Mahtoum</title><link>http://www.horses.com/lookup?Mahtoum</link><description>Registered in: AUS . Ridden by: C. Brown</description><pubDate>Tue, 13 Nov 2006 17:45:00 AEST</pubDate><guid>http://www.horses.com/results/race6273-6</guid></item><item><title>Yeats</title><link>http://www.horses.com/lookup?Yeats</link><description>Registered in: IRE . Ridden by: K. Fallon</description><pubDate>Tue, 13 Nov 2006 17:45:00 AEST</pubDate><guid>http://www.horses.com/results/race6273-7</guid></item><item><title>Activation</title><link>http://www.horses.com/lookup?Activation</link><description>Registered in: NZ . Ridden by: M. Rodd</description><pubDate>Tue, 13 Nov 2006 17:45:00 AEST</pubDate><guid>http://www.horses.com/results/race6273-8</guid></item><item><title>Mandela</title><link>http://www.horses.com/lookup?Mandela</link><description>Registered in: NZ . Ridden by: C. Williams</description><pubDate>Tue, 13 Nov 2006 17:45:00 AEST</pubDate><guid>http://www.horses.com/results/race6273-9</guid></item><item><title>Glistening</title><link>http://www.horses.com/lookup?Glistening</link><description>Registered in: GB . Ridden by: S. Seamer</description><pubDate>Tue, 13 Nov 2006 17:45:00 AEST</pubDate><guid>http://www.horses.com/results/race6273-10</guid></item></channel></rss>
I think this technique is going to be ever more important in the future. Take in some SOAP, spit out some HTML. Take in some XML from one API, spit it out as RSS. A great tool for the toolbox.
Powered by: newtelligence dasBlog 2.3.9074.18820
Disclaimer The opinions expressed herein are my own personal opinions and do not represent my employer's view in anyway.
© Copyright 2010, James Green
E-mail