I have upgraded to Visual Studio 2005 Professional and I now have the XML menu with the Show XSLT Output and Debug XSLT submenu items. Unfortunately, it does not appear to work. I get an error. I searched on the Internet and only found one forum thread about this error so apparently not many developers are trying to debug XSLT. I think this is a clue that not many developers are doing anything complicated with XSL. I’m also not finding much discussion about web parts. XSL can get quite complicated and I think developers really need better tools to work with it. While working with the YouTube API yesterday I ran into three more problems that required solutions. First, I had to construct a link using an XML element in the URL. Second, I had to format a number to use commas to show thousands. And third I needed to convert seconds into minutes. That proved to be the most complicated problem of all.
For the first problem involving the link, I found the solution was to use curly braces to create an attribute value template which allows you to assign a value to an attribute in the output using an expression, rather than a fixed value:
A link with link text.
<xsl:if test="position() mod 2 = 1">
<tr bgcolor="#EFF3FB">
<td valign="top">
<b>From: b>
<a href="http://www.youtube.com/user/{author}">
<xsl:value-of select="author"/>
</
a>
<b> Views: b>
<xsl:value-of select=”format-number(view_count, ‘###,####,###’)“/>
</
td>
</
tr>
</
xsl:if>
An image link.
<td width="150" rowspan="5" valign="top">
<a href="{url}">
<img>
<xsl:attribute name="src">
<xsl:value-of select="thumbnail_url" />
</
xsl:attribute>
</
img>
</
a>
</
td>
The solution to the second problem I had formatting numbers can be found in the code above. You just use the format-number XSLT Function. This will format numbers into thousands with commas. Some videos have millions of views so this was necessary for the view count.The third problem I ran into was due to the YouTube API returning the running time of a video entirely in seconds. However, on the YouTube web site you can see they show the running time in minutes and seconds. Therefore I needed to convert seconds into minutes. Unfortunately, there is no built-in XSLT Function capable of doing time conversions. I did find some JavaScript capable of converting seconds into minutes so I began my quest to use JavaScript within my XSL file. After trying two methods that did not work I finally managed to come up with this code:
1. Declare a namespace for your methods in the
<?xml version="1.0" encoding="utf-8" ?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="urn:schemas-microsoft-com:xslt" xmlns:extension="http://extensionnamespace">
2. Call the JavaScript function in a xsl:value-of select element and pass it a XSL variable. the XSL variable is given the value of a XML element and referenced using a $ sign.
<xsl:if test="length_seconds != ''">
<xsl:if test="position() mod 2 = 1">
<tr bgcolor="#EFF3FB">
<td valign="top">
<xsl:variable name="pos">
<xsl:value-of select="length_seconds"/>
</
xsl:variable>
<xsl:value-of select=”extension:secs2mins($pos)“/>
</
td>
</
tr>
</
xsl:if>
3. Enclose the JavaScript in CDATA tags
<msxsl:script language="JScript" implements-prefix="extension">
[CDATA[
function secs2mins(s) {
var mn = Math.floor((s%3600)/60);
var sec = round2(s%60);
return mn + ':' + sec;
}
function round2(myNumber) {
return Math.floor(Math.round(myNumber * 100)) / 100
}
]]>
</
msxsl:script>