Hello,
I'm using the Data view web part for SharePoint where it randomly takes one quote from a list and displays that quote. I'm recently realized that microsoft extends script usage for xslt using the <msxsl:script> tag to incorporate JScript. This is the code that I've created:
<xsl:stylesheet xmlns:x="http://www.w3.org/2001/XMLSchema"
xmlns:d="http://schemas.microsoft.com/sharepoint/dsp" version="1.0" exclude-result-prefixes="xsl ddwrt msxsl"
xmlns:ddwrt="http://schemas.microsoft.com/WebParts/v2/DataView/runtime"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msxsl="urn:schemas-microsoft-com:xslt"
xmlns:user="http://myCompany.com/">
<msxsl:script language="JScript" implements-prefix="user">
function get_random(maxNum){
if(Math.random && Math.round){
var ranNum = Math.round(Math.random()*(maxNum-1));
ranNum +=1;
return ranNum;
}else {
var today = new Date();
var hours = today.getHours();
var mins = today.getMinutes();
var secs = today.getSeconds();
if(hour == 19){
hour = 18;
}
var ranNum = (((hours+1)*(mins+1)*secs)%maxNum)+1;
return ranNum;
}
}
</msxsl:script>
<xsl:template name="dvt_1.body" xmlns:ddwrt="http://schemas.microsoft.com/WebParts/v2/DataView/runtime" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="urn:schemas-microsoft-com:xslt">
<xsl:param name="Rows"/>
<xsl:param name="FirstRow"/>
<xsl:param name="LastRow"/>
<xsl:for-each select="$Rows">
<xsl:variable name="KeepItemsTogether" select="false()"/>
<xsl:variable name="HideGroupDetail" select="false()"/>
<xsl:variable name="GroupStyle" select="'auto'"/>
<xsl:if test="(position() >= $FirstRow and position() <= $LastRow) or $KeepItemsTogether">
<xsl:if test="not($HideGroupDetail)" ddwrt:cf_ignore="1">
<xsl:if test="position() != 1" ddwrt:cf_ignore="1">
<br>
</br>
</xsl:if>
<xsl:variable name="randomNumber" select="user:get_random($LastRow)"/>
<xsl:choose>
<xsl:when test="$randomNumber = position()">
<xsl:value-of select="@Title "/>
</xsl:when>
</xsl:choose>
</xsl:if>
</xsl:if>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
this doesn't seem to work since I keep getting this error message: "This web part does not have a valid XSLT stylesheet: A name was started with an invalid character." I'm not sure what this error message means.

<msxsl:script> issue
pravej
Thanks for the reply but I still keep getting the same error.
Firstly, it's already wrapped within a CDATA section but if I put it around the <msxsl:script> like you suggested, I get a different error saying the following: The file you imported is not valid. Verify that the file is a Web Part description file (.dwp) and that is contains well form XML.
So, now after making the changes you suggested, there is no change in the error message and it still does not work.
Last Row is defined as the following:
<xsl:variable name="StyleName">PlnTitl</xsl:variable>
<xsl:variable name="Rows" select="/dsQueryResponse/Rows/Row"/>
<xsl:variable name="RowCount" select="count($Rows)"/>
<xsl:variable name="IsEmpty" select="$RowCount = 0"/>
<xsl:call-template name="dvt_1.body">
<xsl:with-param name="Rows" select="$Rows"/>
<xsl:with-param name="FirstRow" select="1"/>
<xsl:with-param name="LastRow" select="$RowCount"/>
</xsl:call-template>
My list has 14 rows so if I do a <xsl:value-of select="$LastRow"> it prints 14.
Paul Russell
The problem is in line 10:
if(Math.random && Math.round){
Content of msxsl:script should be valid text but & in XML has a special meaning and should be escaped as & or wrapped into CDATA section:
<msxsl:script language="JScript" implements-prefix="user"><![CDATA[
function get_random(maxNum){
if(Math.random && Math.round){
var ranNum = Math.round(Math.random()*(maxNum-1));
ranNum +=1;
return ranNum;
}else {
var today = new Date();
var hours = today.getHours();
var mins = today.getMinutes();
var secs = today.getSeconds();
if(hours == 19){
hours = 18;
}
var ranNum = (((hours+1)*(mins+1)*secs)%maxNum)+1;
return ranNum;
}
}
]]></msxsl:script>
In addition I fixed syntax error in the script.
I'd also suggest you convert arguments of script functions to simple types (string, number, boolean):
<xsl:variable name="randomNumber" select="user:get_random(number($LastRow))"/>
If $LastRow happens to be node-set you may have hard time understanding what CLR type you have in script and who to deal with it.
Scott Dorman
HairyDan
You can't have CDATA inside CDATA. It will not be well formed XML.
You can escape '&' as '&' so you will have:
if(Math.random && Math.round){
(This is kind of strange that you imbed XML into XML with CDATA)
count() returns number type so you don't need in explicit type converter in your XSLT.
Mosabama
Thanks
You can mark it as helpful in the header of the post.