Supporters of End User
Web

Unlocking the Mysteries of Data View Web Part XSL Tags - Part 6: xsl:variable

Item is currently unrated. Press SHIFT+ENTER to rate this item.1 star selected. Press SHIFT+ENTER to submit. Press TAB to increase rating. Press SHIFT+ESCAPE to leave rating submit mode.2 stars selected. Press SHIFT+ENTER to submit. Press TAB to increase rating. Press SHIFT+TAB to decrease rating. Press SHIFT+ESCAPE to leave rating submit mode.3 stars selected. Press SHIFT+ENTER to submit. Press TAB to increase rating. Press SHIFT+TAB to decrease rating. Press SHIFT+ESCAPE to leave rating submit mode.4 stars selected. Press SHIFT+ENTER to submit. Press TAB to increase rating. Press SHIFT+TAB to decrease rating. Press SHIFT+ESCAPE to leave rating submit mode.5 stars selected. Press SHIFT+ENTER to submit. Press SHIFT+TAB to decrease rating. Press SHIFT+ESCAPE to leave rating submit mode.
Categories:MOSS; WSS; 2007; 2010; Unlocking the Mysteries of the Data View Web Part; Site Manager/Power User; SharePoint Designer; Data View Web Part; Templates

<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”.

It’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).

Comments

Unlocking the Mysteries of Data View Web Part XSL Tags - Part 7: xsl:for-each | EndUserSharePoint.com

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

[...] you have a rowset like the $Rows I talked about in the prior article about , you’ll want to do something with it.  If you’ve ever [...]

Posted 11-Feb-2010 by Unlocking the Mysteries of Data View Web Part XSL Tags - Part 7: xsl:for-each | EndUserSharePoint.com
Ron

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

Hi Marc,
Nice Article,
Mark i am working on DVWP with Sql Server and i have one Employee table in Sql server with column name ID now i want to filter rows based on ID.
ID hold values like cmiller,charper and so on.
now i have Server Veriable loginUser which store value like domain\cmiller and so on.
i would like to filter based on cmiller so what i did is
but its not working and this same thing work for other webpatrs.

ROn

Posted 11-Feb-2010 by Ron
Ron

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

HI Marc,
I found something interesting to me.I have 4 webparts which display different kind of information for Employee based on current logged in User.as i said in my previous comment 3 of them was working and one of them not.
so what i found is if u enable paging with custom filter like above webparts wont display correct no of data.

Is is know bug while working with Sql Server and DVWP.

THanks
Ron

Posted 11-Feb-2010 by Ron
Kristen

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

Marc,

I’ve burned through a lot of blogs trying to figure out a way to add a complex filter to a DataView. I have field, @Tag, which contains a comma delimited string, and a paramter, $TagsSelected, which is also a comma delimited string. If anyone of the $TagsSelected values are equal to anyone of the @Tag values, I want to display that row. I can not figure out a way to allow for this in XSLT.

Originally, $TagsSelected was only one tag and I was able to use:


However, this didn’t work exactly because if @Tag was ‘Air Force, Army, Navy’ and
$TagsSelected was ‘Air’, it was included in the returned DataSet. ‘Air Force’ does not equal ‘Air’, but ‘Air’ is contained in ‘ Air Force’. Make sense?

Anyway, is there a way for me to use javascript or create an xslt function to use instead of contains that will allow me to traverse through the @Tag string and the $TagsSelected string to see if any of the values match and return TRUE or FALSE?

Posted 09-Mar-2010 by Kristen
AJ Apatzky

dvt_StyleName

Marc, are you able to use this variable within the XSL of a CQWP or is this specific to the DVWP?

Posted 06-Jan-2012 by AJ Apatzky
Joe

Testing on current row in node-set without variable

Hi Marc, im trying to do a fairly complex selection in my Rows variable for my node-set. Ive got two lists in a joined DVWP - one is announcements, the other is a list of communities. The announcements list has a lookup (@CommunityID) to the Communities list. I want to show the current user all Announcements related to Communities where the Community creator (@Author) equals the currentuser. I know why im having problems, i just dont know how to fix it... Here's what im trying to accomplish:
 
<xsl:variable name="Rows" select="/dsQueryResponse/Community_Announcements/Rows/Row[contains(/dsQueryResponse/Communities/Rows/Row[@ID = current()/@CommunityID]/@Author,concat('&gt;',$UserID,'&lt;'))]"/>
 
Ive highlighted my problem... I dont know how to specify that the @ID for the community should equal the @CommunityID of the row i am currenly testing. If i expand that to a dsqueryresponse/Commnuity_Announcements/Rows/Row/@CommunityID it wont work because it doesnt know which row in Announcements i am referring to (i think it assumes i am always referring to the first row).
I can solve this by adding a variable=current row, but that only works if ive already done a for-each row (a test within the rows template)... it wont help with the node-set filter. I'd like to do this on the node-set because doing the test at the row level will still technically return results that i later filter out, but this is a problem if i want to specify an count(Rows) - 0 type scenario (ie: no results).
 
Any help?
 
Thanks,
 
Joe H

Posted 29-Feb-2012 by Joe
Joe H

Solved - sort-of

Intrestingly enough, the Xpath editor in designer was returning results while my page was not, using the same code. I never got that to work so i approached it a different way. I created a new node-set like so:
 
<xsl:variable name="theseRows">
   <xsl:for-each select="$Rows">
    <xsl:variable name="thisCID" select="@CommunityID"/>
     <xsl:if test="(contains(/dsQueryResponse/Communities/Rows/Row[@ID=$thisCID]/@Author,$UserID) or contains(/dsQueryResponse/Communities/Rows/Row[@ID=$thisCID]/@Members,$UserID)) and (/dsQueryResponse/Communities/Rows/Row[@ID=$thisCID]/@Active = 1) and number(ddwrt:FormatDateTime(string(@Expires),2057,'yyyyMMdd')) &gt;= number(ddwrt:FormatDateTime(string(ddwrt:TodayIso()),2057,'yyyyMMdd'))">
      <xsl:copy-of select="."/>
     </xsl:if>
   </xsl:for-each>
  </xsl:variable>
 
Anything within that IF statment could be changed to your own criteria... i had quite a few.
 
then i referenced that nodeset in the body template (in order to create my rows in the rows template) with:
 
<xsl:for-each select="msxsl:node-set($theseRows)/*">
<xsl:call-template name="dvt_1.rowview" />
</xsl:for-each>
 
I was also able to change my rowcount by referencing this new node-set rather than the original $Rows node-set

Posted 01-Mar-2012 by Joe H

Notify me of comments to this article

E-mail:
   

Add Comment

Title:

 
Comment:
Email:

   


Name:

 
Url: