Using JavaScript Within XSL

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  element

<?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>

This entry was posted in General. Bookmark the permalink.

Leave a Reply

Your email address will not be published. Required fields are marked *

Time limit exceeded. Please complete the captcha once again.