Unlocking the Mysteries of Data View Web Part XSL Tags – Part 6 – <xsl:variable>

This entry is part 6 of 21 in the series Unlocking the Mysteries of Data View Web Part XSL Tags

Cross-posted from EndUserSharePoint.com

<xsl:variable>

A value you create for use within a template which is only defined within the scope of that template.

Parameters and variables are used interchangeably, but how you create them is a bit different. While a parameter is a value which you expect to receive, a variable is something which you define. You refer to both of them with a preceding dollar sign once they are defined.

<xsl:variable> lets you create all sorts of values, from simple static values like:

<xsl:variable name="MyName" select="’Marc’"/>

to much more complex concepts like filtered, joined rowsets (this is a real example from a client project):

<xsl:variable name="Discipline" select="/dsQueryResponse/SDLC_Artifact_Groups/Rows/Row[@Title = (/dsQueryResponse/SDLC_Artifacts_2010/Rows/Row[ddwrt:AutoNewLine(string(@Title)) = current()/@Artifact_x0020_Name]/@Artifact_x0020_Group)]/@Discipline"/>

Most likely, as you’re getting up to speed with Data View Web Parts, you’re going to want to define relatively simple variables. All variables need to have:

  • A name – This is how you refer to the variable once you’ve created it, like $MyName or $Discipline
  • A value – You define the value either with a select or “within” the tag (more below).

Here are some relatively straightforward examples:

<xsl:variable name=”OnHand” select=”@Inventory + @Returned”/>
<xsl:variable name=”TotalCost” select=”sum(@Cost)”/>
<xsl:variable name=”RowNumber” select=”position()”/>

If we look at the example XSL again, we can see that there are <xsl:variable> tags used in a few places:

<XSL><xsl:stylesheet xmlns:x="<a href="http://www.w3.org/2001/XMLSchema">http://www.w3.org/2001/XMLSchema</a>" xmlns:d="<a href="http://schemas.microsoft.com/sharepoint/dsp">http://schemas.microsoft.com/sharepoint/dsp</a>" version="1.0" exclude-result-prefixes="xsl msxsl ddwrt" xmlns:ddwrt="<a href="http://schemas.microsoft.com/WebParts/v2/DataView/runtime">http://schemas.microsoft.com/WebParts/v2/DataView/runtime</a>" xmlns:asp="<a href="http://schemas.microsoft.com/ASPNET/20">http://schemas.microsoft.com/ASPNET/20</a>" xmlns:__designer="<a href="http://schemas.microsoft.com/WebParts/v2/DataView/designer">http://schemas.microsoft.com/WebParts/v2/DataView/designer</a>" xmlns:xsl="<a href="http://www.w3.org/1999/XSL/Transform">http://www.w3.org/1999/XSL/Transform</a>" xmlns:msxsl="urn:schemas-microsoft-com:xslt" xmlns:SharePoint="Microsoft.SharePoint.WebControls" xmlns:ddwrt2="urn:frontpage:internal">

  <xsl:output method="html" indent="no"/>
  <xsl:decimal-format NaN=""/>
  <xsl:param name="dvt_apos">'</xsl:param>
  <xsl:variable name="dvt_1_automode">0</xsl:variable>

  <xsl:template match="/">
    <xsl:call-template name="dvt_1"/>
  </xsl:template>

  <xsl:template name="dvt_1">
    <xsl:variable name="dvt_StyleName">Table</xsl:variable>
    <xsl:variable name="Rows" select="/dsQueryResponse/Rows/Row"/>
    <table border="0" width="100%" cellpadding="2" cellspacing="0">
      <tr valign="top">
        <xsl:if test="$dvt_1_automode = '1'" ddwrt:cf_ignore="1">
          <th width="1%" nowrap="nowrap"></th>
        </xsl:if>
        <th nowrap="nowrap">Title</th>
      </tr>
      <xsl:call-template name="dvt_1.body">
        <xsl:with-param name="Rows" select="$Rows"/>
      </xsl:call-template>
    </table>
  </xsl:template>

  <xsl:template name="dvt_1.body">
    <xsl:param name="Rows"/>
    <xsl:for-each select="$Rows">
      <xsl:call-template name="dvt_1.rowview"/>
    </xsl:for-each>
  </xsl:template>

  <xsl:template name="dvt_1.rowview">
    <tr>
      <xsl:if test="position() mod 2 = 1">
        <xsl:attribute name="class">ms-alternating</xsl:attribute>
      </xsl:if>
      <xsl:if test="$dvt_1_automode = '1'" ddwrt:cf_ignore="1">
        <td width="1%" nowrap="nowrap">
          <span ddwrt:amkeyfield="ID" ddwrt:amkeyvalue="ddwrt:EscapeDelims(string(@ID))" ddwrt:ammode="view"></span>
        </td>
      </xsl:if>
      <td>
        <xsl:value-of select="@Title"/>
      </td>
    </tr>
  </xsl:template>
</xsl:stylesheet></XSL>

Here’s a description of the variables which we see above:

<xsl:variable name="dvt_1_automode">0</xsl:variable>

This defines a simple variable called dvt_1_automode with a value of “0”. I’m going to gloss over what this is used for, but note that rather than using the select attribute, you can also define the value of a variable “inside” the tag. This method is handy if you want to use some script to define a value.

<xsl:variable name="dvt_StyleName">Table</xsl:variable>

This is another simple text value being assigned to a variable. SharePoint Designer creates this variable to represent the layout type you are using for your DVWP. I’ve never seen it used in any way, and I generally remove it.

<xsl:variable name="Rows" select="/dsQueryResponse/Rows/Row"/>

This is the single most important variable you will see in a DVWP. This is where we define a variable called Rows which represents the rowset we’ve gotten back from our DataSource. Note that the variable can be called Bob or Strawberry_Jam (note no spaces); Designer just uses the useful mnemonic Rows.

clip_image002It’s best from an efficiency perspective to add filters to the CAML so that you retrieve as few items as possible to meet your needs. When you set a filter in the Common Data View Tasks, that’s where the filter ends up: in the CAML. However, you may want to further filter the rowset more dynamically, like in the case where you’ve got a parameter on the Query String. When you want to do this more dynamic filtering, you can do it in the definition of the Rows like this:

<xsl:variable name="Rows" select="/dsQueryResponse/Rows/Row[@ID = $ID]"/>

Anything you place inside the brackets should evaluate to true or false: if the calculation returns true, the item is included in the rowset; if it returns false, the item is not included.

What you can calculate for the value of a variable is pretty much endless. One extremely useful set of functions is available in the ddwrt namespace. Why this isn’t documented more completely and visibly by Microsoft is beyond me, as some of these functions are useful all the time. Thank goodness for Serge van den Oever’s work on this or we would have nothing.

Next up: <xsl:for-each>

A way to iterate over a nodeset (group of rows).

Series Navigation<< Unlocking the Mysteries of Data View Web Part XSL Tags – Part 5 – <xsl:param>Unlocking the Mysteries of Data View Web Part XSL Tags – Part 7 – <xsl:for-each> >>

12 Comments

  1. hi,
    Need your help on the below example.(DVWP)

    I grouped a filed title and caluculated sum for every indiual group.but i need to calculated for only one perticular group and that total should be shown in a seperate variable.

    A(group)
    total:251

    B(group)
    total:210

    if i caluculate sum it was showinf for all grouped columns and rows.but i dont want like that i want only for B(group).can you please help me on this.

    Reply
    • It’s hard to tell exactly what you’re trying to do and what’s going on, but you should be able to accomplish what you want by customizing the XSL. You’ll need a condition on the totalling logic to only display for group B.

      M.

      Reply
  2. Great post!

    I have a performance question though with these filters. I am using a DVWP on a linked data source. The linked data source contains 2 lists. One list may eventually surpass 5000 items. I am worried about hitting SharePoint’s query size limit. If I apply XSL filtering to my DVWP, will this prevent me from hitting this limit?

    For example, this list that may eventually surpass 5000 items grows 300 items per month. If I apply an XSL filter by Month and Year, will this avoid hitting the query size limit?

    Reply
    • I can’t be sure you won’t hit the limit without fully understanding your data, but a filter in the XSL doesn’t reduce the number of items returned by the query. To make it less likely that you will hit the limit, do as much filtering as you can in CAML, as that reduces the number of items returned.

      M.

      Reply
      • Thank you for the reply. I also downloaded “SharePoint 2010 at Work: Tricks, Traps, and Bold Opinions” after you mentioned it in another post. It has some excellent information… thanks!

        Reply
  3. Hi Marc

    I need to filter a DVWP where a column contains or doesnt contain values.Ive tried using /dsQueryResponse/Rows/Row[(contains(@ColumnName,$queryvar))] but it would work fine if @ColumnName contains some value..How do I query empty values within the column..Its a datetime field.

    Reply
  4. In a nutshell,I’d wanna to filter by both conditions..contains and doesnt contain..How can I achieve this thru query string/CAML..since it would take only 1 condition either contains or not contains..so I wud be able to fetch only values that are there in the field.How wud it return those rows where this column has no values..

    Reply
    • Okay, if you want all items regardless what the value is, you can’t filter in your CAML. The string-length test would look like:

      /dsQueryResponse/Rows/Row[string-length(@ColumnName) &gt; 0]
      

      M.

      Reply
  5. Hi Marc

    Thanks a lot..I had to define both the upper and lower limits here i.e [(string-length(@ColumnName)>$QSvariable and string-length(@ColumnName)<=$QSvariable1)or $QSvariable ='*'] as my requirements covered both less than 0 and more than 0 and all..and it worked..

    Reply

Leave a Reply