Jon's Radio : Jon Udell's Radio Blog

 

Note: Jon's Radio has moved to InfoWorld

storyList


Click to see the XML version of this web page.

Click here to send an email to the editor of this weblog.

 
 

An XSLT Tutorial

I read today about a new Radio driver to pull NASA announcements into the news page, and it made me wonder about an XSLT alternative. The Liftoff channel, in the right column, is the result of my wondering. As I am not an XSLT expert, I record here for my own future benefit as much as yours how I got to the solution.

Although often used to transform XML to HTML, you can also use XSLT to transform one kind of XML to another. In this case, I wanted to transform some newsy but non-RSS XML into an RSS .92 feed that Radio could directly consume.

(Along the way, I fetched my own RSS feed to see what needed to be generated. I was horrified to see that my RSS feed was broken since I mentioned Hannes Wallnöfer in a title back on the 14th! It's one of those sneaky entity encoding problems. Other channels are affected too. Since I was busy thinking about XSLT, I just worked around the problem by misspelling Hannes' last name in the affected item.)

Here's the XSL file that does the job:

<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="
http://www.w3.org/1999/XSL/Transform" version="1.0">

<xsl:output method="xml" indent="yes" encoding="iso-8859-1"/>
   
<xsl:template match="/newsfeed"> <!-- match the root -->
<rss version="0.92">
<channel>
<xsl:apply-templates select="channel"/> <!-- emit channel elements -->
</channel>
</rss>
</xsl:template>

<xsl:template match="channel">
<xsl:if test="@id='Liftoff'">                        <!-- select one of the three feeds -->
<title><xsl:value-of select="@id"/></title>   <!-- convert attributes to elements -->
<link><xsl:value-of select="@url"/></link>
<description><xsl:value-of select="@name"/></description>

<xsl:apply-templates select="item"/>           <!-- process items -->
</xsl:if>
</xsl:template>

<xsl:template match="item">
<item>
<link><xsl:value-of select="href"/></link>
<title><xsl:value-of select="title"/></title>
<description><xsl:value-of select="intro"/></description>
</item>
</xsl:template>

</xsl:stylesheet>

I tested this locally in IE. Because IE won't render the output as XML, I wound up using this HTML code in a file called nasa.html:

<html>
<head>
<script>
function transform()
{
var xml = new ActiveXObject("Microsoft.XMLDOM");
var xsl = new ActiveXObject("Microsoft.XMLDOM");
xml.async = false;
xsl.async = false;
xsl.load('nasa.xsl');
xml.load('http://liftoff.msfc.nasa.gov/Content.xml');
var theString = xml.transformNode(xsl);
document.write (theString);
}
</script>

</head>
<body>
<a href="javascript:transform()">transform</a>
</body>

I loaded nasa.html into IE, clicked transform to process the XML through the stylesheet, then used View Source to see the transformed XML. Kind of awkward. Sometimes I'll instead use the Windows Scripting Host to dump the output to a file, but WSH isn't installed on this machine.

It took longer to get this working than it should have. Mainly, that's because the NASA file really has three different newsfeeds in it. I finally decided to just select one of them. The XSLT file can in principle be parameterized to choose any of the three, but that's implementation-dependent, and as we'll see, I wanted to use a publicly-available implementation.

Once I was producing what looked like a valid RSS feed from the NASA file, I went looking for a public XSLT service that I'd seen Aaron Swartz using somewhere. It worked. Now I could form a URL that combined my XSLT file, publicly available in my Gems directory, with NASA's XML, to yield an RSS 0.92 feed that Radio (or any other RSS reader) can consume. And nobody has to install any software to do it.

Moral #1: There's More Than One Way To Do It.

Moral #2: Keep an eye on your RSS feed :-)

Moral #3: Entity encoding/decoding problems are everywhere. I created a new one for myself, by using the W3C service, and had to make a slight change (from rssUrl to string.urlEncode(rssUrl)) to solve it.

Moral #4: There are lots of Web services. They don't have to be packaged in WSDL or SOAP or XML-RPC to be useful.



© Copyright 2002 Jon Udell.
Last update: 8/6/2002; 12:46:19 AM.

Click here to visit the Radio UserLand website.