I'm trying to retrieve a different set of data and assign it to a variable depending on the existance of a parameter.. If the parameter solutionType exists I wanted to filter the list of customers for testimonials by that solutionType, iterate over them and pick one at random..
unfortunately I can't output using the $allCustomers syntax as it throws the following error: System.Xml.Xsl.XslTransformException: To use a result tree fragment in
a path expression, first convert it to a node-set using the
msxsl:node-set() function.
i use that syntax and alas the count next to our clients say is permanently set to 1 instead of the number of testimonials i know should be there..
<msxsl:script language="c#" implements-prefix="randomTools"> <msxsl:assembly href="../bin/umbraco.dll"/> <![CDATA[ /// <summary> /// Gets a random integer that falls between the specified limits /// </summary> /// <param name="lowerLimit">An integer that defines the lower-boundary of the range</param> /// <param name="upperLimit">An integer that defines the upper-boundary of the range</param> /// <returns>A random integer within the specified range</returns> public static int GetRandom(int lowerLimit,int upperLimit) { Random r = umbraco.library.GetRandom(); int returnedNumber = 0; lock (r) { returnedNumber = r.Next(lowerLimit, upperLimit); } return returnedNumber; } ]]> </msxsl:script> </xsl:stylesheet>
If i remove the xsl choose and when and just assign allCustomers using a select in the opening tag using either of the conditions it works as expected.
Can't test it right now, but I'd say you should try using copy-of instead of value-of when selecting nodes for a variable, otherwise you're explicitly asking for the string value of the expression, which also makes sense of the constant "1" count (one text node only)...
So:
<xsl:copy-of select="umbraco.library:GetXmlNodeById(/macro/allCustomerCategories)/node[data[@alias = 'solutionType'] = $solutionType]/node[@nodeTypeAlias = 'Customer' and data [@alias = 'umbracoNaviHide'] != 1]" />
thanks I had another look at it was actually once assigning the variable when using i needed to select the node of the variable to get the correct count and behaviour!
<msxsl:script language="c#" implements-prefix="randomTools"> <msxsl:assembly href="../bin/umbraco.dll"/> <![CDATA[ /// <summary> /// Gets a random integer that falls between the specified limits /// </summary> /// <param name="lowerLimit">An integer that defines the lower-boundary of the range</param> /// <param name="upperLimit">An integer that defines the upper-boundary of the range</param> /// <returns>A random integer within the specified range</returns> public static int GetRandom(int lowerLimit,int upperLimit) { Random r = umbraco.library.GetRandom(); int returnedNumber = 0; lock (r) { returnedNumber = r.Next(lowerLimit, upperLimit); } return returnedNumber; } ]]> </msxsl:script> </xsl:stylesheet>
Conditional Variable Assignment & Use
Hi All,
I'm trying to retrieve a different set of data and assign it to a variable depending on the existance of a parameter.. If the parameter solutionType exists I wanted to filter the list of customers for testimonials by that solutionType, iterate over them and pick one at random..
unfortunately I can't output using the $allCustomers syntax as it throws the following error: System.Xml.Xsl.XslTransformException: To use a result tree fragment in a path expression, first convert it to a node-set using the msxsl:node-set() function.
i use that syntax and alas the count next to our clients say is permanently set to 1 instead of the number of testimonials i know should be there..
does anyone know what the problem could be?
Regards,
Tom
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE xsl:stylesheet [<!ENTITY nbsp " ">]>
<xsl:stylesheet
version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msxml="urn:schemas-microsoft-com:xslt"
xmlns:msxsl="urn:schemas-microsoft-com:xslt"
xmlns:umbraco.library="urn:umbraco.library"
xmlns:randomTools="http://www.umbraco.org/randomTools"
exclude-result-prefixes="msxml umbraco.library msxsl randomTools">
<xsl:output method="xml" omit-xml-declaration="yes" />
<xsl:param name="currentPage"/>
<xsl:variable name="solutionType" select="/macro/solutionType" />
<xsl:variable name="maxItems" select="number(1)" />
<xsl:variable name="allCustomers">
<xsl:choose>
<xsl:when test="string($solutionType) != ''">
<xsl:value-of select="umbraco.library:GetXmlNodeById(/macro/allCustomerCategories)/node [string(data [@alias='solutionType']) = $solutionType]/node [@nodeTypeAlias = 'Customer' and string(data [@alias='umbracoNaviHide']) != '1']" />
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="umbraco.library:GetXmlNodeById(/macro/allCustomerCategories)//node [@nodeTypeAlias = 'Customer' and string(data [@alias='umbracoNaviHide']) != '1']" />
</xsl:otherwise>
</xsl:choose>
</xsl:variable >
<xsl:template match="/">
<div class="testimonialstitle">
Our clients say: <xsl:value-of select="count(msxsl:node-set($allCustomers))"/>
</div>
<xsl:for-each select="msxml:node-set($allCustomers)">
<xsl:sort select="randomTools:GetRandom(0,count(msxsl:node-set($allCustomers)))" order="ascending" />
<xsl:if test="position() <= $maxItems">
<span class="testimonialstext">
<img src="/images/start-quote.jpg"/>
<xsl:value-of select="data [@alias = 'testimonialText']" disable-output-escaping="yes" />
<img src="/images/end-quote.jpg"/>
</span>
</xsl:if>
</xsl:for-each>
</xsl:template>
<msxsl:script language="c#" implements-prefix="randomTools">
<msxsl:assembly href="../bin/umbraco.dll"/>
<![CDATA[
/// <summary>
/// Gets a random integer that falls between the specified limits
/// </summary>
/// <param name="lowerLimit">An integer that defines the lower-boundary of the range</param>
/// <param name="upperLimit">An integer that defines the upper-boundary of the range</param>
/// <returns>A random integer within the specified range</returns>
public static int GetRandom(int lowerLimit,int upperLimit) {
Random r = umbraco.library.GetRandom();
int returnedNumber = 0;
lock (r)
{
returnedNumber = r.Next(lowerLimit, upperLimit);
}
return returnedNumber;
}
]]>
</msxsl:script>
</xsl:stylesheet>
If i remove the xsl choose and when and just assign allCustomers using a select in the opening tag using either of the conditions it works as expected.
Hi Tom,
Can't test it right now, but I'd say you should try using copy-of instead of value-of when selecting nodes for a variable, otherwise you're explicitly asking for the string value of the expression, which also makes sense of the constant "1" count (one text node only)...
So:
Hope that does it,
/Chriztian
Hi Chriztian!
thanks I had another look at it was actually once assigning the variable when using i needed to select the node of the variable to get the correct count and behaviour!
here's the solution
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE xsl:stylesheet [<!ENTITY nbsp " ">]>
<xsl:stylesheet
version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msxml="urn:schemas-microsoft-com:xslt"
xmlns:msxsl="urn:schemas-microsoft-com:xslt"
xmlns:umbraco.library="urn:umbraco.library"
xmlns:randomTools="http://www.umbraco.org/randomTools"
exclude-result-prefixes="msxml umbraco.library msxsl randomTools">
<xsl:output method="xml" omit-xml-declaration="yes" />
<xsl:param name="currentPage"/>
<xsl:variable name="solutionType" select="/macro/solutionType" />
<xsl:variable name="maxItems" select="number(1)" />
<xsl:variable name="allCustomers">
<xsl:choose>
<xsl:when test="string($solutionType) != ''">
<xsl:copy-of select="umbraco.library:GetXmlNodeById(/macro/allCustomerCategories)/node[data[@alias = 'solutionType'] = $solutionType]/node[@nodeTypeAlias = 'Customer' and data [@alias = 'umbracoNaviHide'] != 1]" />
</xsl:when>
<xsl:otherwise>
<xsl:copy-of select="umbraco.library:GetXmlNodeById(/macro/allCustomerCategories)//node [@nodeTypeAlias = 'Customer' and string(data [@alias='umbracoNaviHide']) != '1']" />
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:variable name="filteredCustomers" select="msxsl:node-set($allCustomers)"/>
<xsl:template match="/">
<div class="testimonialstitle">
Our clients say: <xsl:value-of select="count(msxsl:node-set($filteredCustomers/node))"/>
</div>
<xsl:for-each select="msxml:node-set(msxsl:node-set($filteredCustomers/node))">
<xsl:sort select="randomTools:GetRandom(0,count($filteredCustomers/node))" order="ascending" />
<xsl:if test="position() <= $maxItems">
<span class="testimonialstext">
<img src="/images/start-quote.jpg"/>
<xsl:value-of select="data [@alias = 'testimonialText']" disable-output-escaping="yes" />
<img src="/images/end-quote.jpg"/>
</span>
</xsl:if>
</xsl:for-each>
</xsl:template>
<msxsl:script language="c#" implements-prefix="randomTools">
<msxsl:assembly href="../bin/umbraco.dll"/>
<![CDATA[
/// <summary>
/// Gets a random integer that falls between the specified limits
/// </summary>
/// <param name="lowerLimit">An integer that defines the lower-boundary of the range</param>
/// <param name="upperLimit">An integer that defines the upper-boundary of the range</param>
/// <returns>A random integer within the specified range</returns>
public static int GetRandom(int lowerLimit,int upperLimit) {
Random r = umbraco.library.GetRandom();
int returnedNumber = 0;
lock (r)
{
returnedNumber = r.Next(lowerLimit, upperLimit);
}
return returnedNumber;
}
]]>
</msxsl:script>
</xsl:stylesheet>
is working on a reply...