views:

73

answers:

1

I have a basic XSLT filter on a SharePoint 2007 DataFormWebPart:

<xsl:variable name="Rows" select="/dsQueryResponse/Rows/Row[((ddwrt:FormatDateTime(string(@MyDate) ,1061 ,'MM'))=$MyParameter)]"/>

The $MyParameter comes from an ASP.NET control. But trying to set the variable value in any other ways results in an error:

<xsl:variable name="Rows">
<xsl:value-of select="/dsQueryResponse/Rows/Row[((ddwrt:FormatDateTime(string(@MyDate) ,1061 ,'MM'))=$MyParameter)]"/>
</xsl:variable>

or

<xsl:variable name="Rows">
/dsQueryResponse/Rows/Row[((ddwrt:FormatDateTime(string(@MyDate) ,1061 ,'MM'))=$MyParameter)]
</xsl:variable>

The error I get is: Argument 1 must return a node-set. -->count($Rows)<--

Ultimately, I am trying to achieve something similar:

<xsl:variable name="Rows">
<xsl:choose>
  <xsl:when test="($MyParameter2 = '1')">
    <xsl:value-of select="/dsQueryResponse/Rows/Row[((ddwrt:FormatDateTime(string(@MyDate) ,1061 ,'MM'))=$MyParameter)]"/>
  </xsl:when>
  <xsl:otherwise>
    <xsl:value-of select="/dsQueryResponse/Rows/Row[((ddwrt:FormatDateTime(string(@MyDate) ,1061 ,'MM'))=$otherParameter)]"/>
  </xsl:otherwise>
</xsl:choose>
</xsl:variable>

Is anything like this possible with XSLT or I should look for other possibilities withing SharePoint Designer?

+5  A: 

When you use the count() function, it counts the nodes in the node-set specified in the parameter.

The other two ways that you are trying to construct the $Rows variable are assigning Strings, not node-sets.

  1. When you set the variable the first way, your select statement returns a node-set from the evaluated XPATH expression.

  2. xsl:value-of returns a string. So, when you create your variable the second way, you are assigning the string value of the node-set that was selected with your XPATH.

  3. Placing string a string inside the xsl:variable, as you have done the third way, assigns that string value to the $Rows variable. Although that value happens to be an XPATH expression, it does not get evaluated as such. It simply assigns the literal string "/dsQueryResponse/Rows/Row[((ddwrt:FormatDateTime(string(@MyDate) ,1061 ,'MM'))=$MyParameter)]" to the $Rows variable.

Solution: Try combining your XPATH criteria into a single select statement and incorporating the logic to test for the $MyParameter2 value in the predicate filter:

<xsl:variable name="Rows" 
    select="/dsQueryResponse/Rows/Row[
        ((ddwrt:FormatDateTime(string(@MyDate) ,1061 ,'MM'))=$MyParameter) 
        and $MyParameter2='1'
      ] 
  | 
    /dsQueryResponse/Rows/Row[
        ((ddwrt:FormatDateTime(string(@MyDate) ,1061 ,'MM'))=$otherParameter) 
        and $MyParameter2 !=1
       ]" 
 />
Mads Hansen
+1 Good answer. I think this time you could use `or` operator to reduce the expression.
Alejandro
Good answer, +1.
Dimitre Novatchev
@Indrek, you could probably improve the performance of this by creating a key, `<xsl:key name="rowsByDateTime" match="/dsQueryResponse/Rows/Row" use="ddwrt:FormatDateTime(string(@MyDate) ,1061 ,'MM'))" />`; and then using that key: `select="key('rowsByDateTime', $MyParameter)[$MyParameter2 = '1'] | key('rowsByDateTime', $otherParameter)[$MyParameter2 !=1]`
LarsH