Unlocking the Mysteries of Data View Web Part XSL Tags – Part 1: Overview

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

Cross-posted from EndUserSharePoint.com

Data View Web Parts (DVWPs) are, to me, the most powerful feature in SharePoint. You’ve probably heard them called the Swiss Army Knife of SharePoint and there’s really very little that you can’t display with them if you understand how they work. But understanding the inner working of DVWPs requires knowledge of some pretty crufty concepts: CAML and XSL. In this series, I hope to demystify the XSL side of things a bit by explaining the most common XSL tags you’re likely to see in DVWPs and what you can do with them.

For this first post in the series, let me list out what I see as the most common XSL tags used in DVWPs generated only by using SharePoint Designer’s dialogs. You’re liable to see most, if not all, of these tags if you switch to Split or Code view and start rummaging around in the code. The definitions are mine, and I intend them to be simplistic, so you purists out there may need to check your vocabulary at the door!

<xsl:template>
Think of a template as a subroutine. It’s a unit of XSL to which you pass control.

<xsl:call-template>
This is how you call a template which you’ve defined with <xsl-template>.

<xsl:with-param>
You use this with <xsl:call-template> when you want to pass a value into a template, usually a value that varies.

<xsl:param>
A value you’ve passed into a template with <xsl:with-param>. You need to have an <xsl:param> at the top of the template for each value you expect to be passed into it.

<xsl:variable>
A value you create for use within a template which is only defined within the scope of that template.

<xsl:for-each>
A way to iterate over a nodeset (group of rows).

<xsl:sort>
Used within an <xsl:for-each> to determine the sort order in which the nodeset (group of rows) are processed.

<xsl:if>
A single conditional test. If the test is true, then the contained code is executed.

<xsl:choose>
Like <xsl:if>, but with multiple possibilities, more like if-then-else.

<xsl:when>
Used within <xsl:choose> as a conditional test. If the test is true, then the contained code is executed and the <xsl:choose> is exited.

<xsl:otherwise>
Used within <xsl:choose> as the “fall-back” condition. If none of the prior <xsl:when>s have been executed, the code contained here is executed.

<xsl:value-of>
Outputs the value to which it evaluates, whether it be the value of a column, a variable, etc.

There are more XSL tags available, but this set is what you are most likely to run into in a Data View Web Part (DVWP). As we continue on with this series, I’ll give some examples of how you may see each of these tags used, some other interesting things you might want to do, and the results.

Unlocking the Mysteries of Data View Web Part XSL Tags – Part 2 – <xsl:template>

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

Cross-posted from EndUserSharePoint.com

<xsl:template>
Think of a template as a subroutine. It’s a unit of XSL to which you pass control.

A template in a Data View Web Part’s (DVWP’s) XSL is a really important “unit of measure”. When you first drop a DVWP on the page and configure it, SharePoint Designer will automagically create a default set of templates for you. These templates are the scaffolding that holds up the XSL. They are the containers into which you place pretty much everything else (with a few exceptions) and the way that you control the logical flow of the XSL.

If you take the absolutely simplest (and most common) set of actions (drop a DVWP on the page and simply choose to display a list’s Title in a Multiple Item View), you’ll end up with some XSL that looks something like the code example below.

String Bean ManAside: In this series, I’m going to subject you to my old pal String Bean Man from Office Clip Art. He’s going to point things out to you which I consider best practices, having been writing DVWPs for years. You don’t have to agree with these tips or follow them, but they work well for me. Here’s the first one: The code you end up with won’t look exactly like this because absolutely the first thing that I do when I work in a DVWP is to clean up the code by making the indenting consistent. (I like to use tabs, but in the example below, I’ve used two spaces for each indent, which looks better here at good old EUSP.)

Because SharePoint Designer is fundamentally a code generator, it creates code that contains “stubs” for things that you *may* want to do later. I’ve left everything as is below except for cleaning up the indentations and white space.

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

If you look through this example, you’ll see that there are four templates:

<xsl:template match="/">
<xsl:template name="dvt_1">
<xsl:template name="dvt_1.body">
<xsl:template name="dvt_1.rowview">

There’s nothing magic about the fact that there are four or what their names are. SharePoint Designer just creates templates with these names every time. Each of these templates has a specific purpose, as things are currently set up:

<xsl:template match="/">

Matches the “root” of the nodeset tree. The way I think about this is that it is the “initiating function”.

<xsl:template name="dvt_1">

This template is where the nodeset (set of rows) is retrieved from the DataSource and the rendered output is started (in this case).

<xsl:template name="dvt_1.body">

This template is where things which should happen at the nodeset level will occur. For instance, if you decide to sort the rows, it will happen here.

<xsl:template name="dvt_1.rowview">

This is the “meat” of the DVWP, where we work with each row, outputting the values.

String Bean ManAnother thing that I do early in my editing is to rename the templates to better reflect what I’m doing. In this case, I’m working with my standard Sales Opportunities demo list, so I’d rename the templates like this:

<xsl:template match="/">
<xsl:template name="Sales_Opportunities">
<xsl:template name="Sales_Opportunities.body">
<xsl:template name=”Sales_Opportunities.rowview">

There’s no requirement to do this, but it can make things easier down the road, especially if you decide to use additional lists in the DVWP (an AggregateDataSource). “dvt_1” just doesn’t feel that descriptive to me.

In this example (which I will continue to use in this series), each template passes control to the next (using <xsl:call-template>, but that’s the next article), as appropriate. I’ll go into the specifics of how that works and what happens in each of the templates later in the series, but this is a high level view of what they are there for and what they each do.

Unlocking the Mysteries of Data View Web Part XSL Tags – Part 3 – <xsl:call-template>

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

Cross-posted from EndUserSharePoint.com

<xsl:call-template>

This is how you call a template which you’ve defined with <xsl-template>.

imageIn the last installment, I showed you what templates SharePoint Designer usually creates when you set up a Data View Web Part (DVWP). Having the templates in place is great, but you need a way to chain them together to make them do anything. That’s where <xsl:call-template> comes in.

Hopefully, even if you don’t have a programming background, this can make sense. Look at the diagram to the right and think of this like a flow chart. Each of the blue squares represents an <xsl:template>, and the arrows represent how <xsl:call-template> allows you to pass control from one template to the next. (The arrows are on the right and left just to make it look better; there’s no distinction intended.)

The order in which you call the templates makes a difference, of course. You need to put on your socks before your shoes; cook dinner before you can eat it, watch TV, and go to bed, etc.

If you look at the sample XSL again, you’ll see where <xsl:call-template> is used:

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

You’ll see that each of the first three templates uses <xsl:call-template> to pass control along. The dvt_1.rowview template doesn’t use <xsl:call-template> because it’s the “end of the line”.

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

<xsl:template name="dvt_1">
  <xsl:call-template name="dvt_1.body">
    …
  </xsl:call-template>
</xsl:template>

<xsl:template name="dvt_1.body">
  <xsl:call-template name="dvt_1.rowview"/>
</xsl:template>

Note that the code section above is just the skeleton to show you how things fit together; it isn’t valid XSL.

Here’s a little bonus trick you can use to see the raw XML which is being returned from your DataSource. If you drop this XSL section in, replacing everything between the <XSL> and </XSL> tags, you’ll be able to see the raw XML as it’s coming back from your DataSource. This is handy when you’re working on displaying the results from a Search more nicely, but also anytime you just want to know exactly what’s in the result set.

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:ddwrt2="urn:frontpage:internal">
  <xsl:template match="@*|node()">
    <xsl:copy>
      <xsl:apply-templates select="@*|node()" />
    </xsl:copy>
  </xsl:template>
</xsl:stylesheet>

Depending on where you use this trick, you’ll probably need to View Source for the page to see the results. Search for <dsQueryResponse> and you’ll see the rows which are returned from the DataSource.

Next up: <xsl:with-param>. You use this with <xsl:call-template> when you want to pass a value into a template, usually a value that varies.

Unlocking the Mysteries of Data View Web Part XSL Tags – Part 4 – <xsl:with-param>

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

Cross-posted from EndUserSharePoint.com

<xsl:with-param>

You use this with <xsl:call-template> when you want to pass a value into a template, usually a value that varies.

Once you’ve laid down the foundation and framed the rooms with <xsl:template> and <xsl:call-template> (one of my goals in this series is to mix as many metaphors as possible), you can start building out. <xsl:with-param> is the way you can send variable information into a template for it to work with. Templates need some fodder to work with (see: another metaphor!) and <xsl:with-param> is a way to provide it.

<xsl:with-param> can only be used with <xsl:call-template>, so it passes the value into the template which you are calling just like you would do with a function or procedure in many other programming languages. If we look at the standard example again, you can see that some <xsl:call-template>s pass in parameters and some do not:

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

So you can see that the call to dvt_1.body passes the Rows parameter:

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

and the call to the dvt_1 template passes no parameters:

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

(There’s also a sort of “implied” parameter pass with <xsl:for-each>, but that will have to wait for the <xsl:for-each> installment.)

If you set some of the options on a DVWP, you may see a longer list of parameters passed into a template. For instance, if you turn on paging, you’ll see this in the call to dvt_body:

<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="$LastRow - $FirstRow + 1" />
</xsl:call-template>

These extra values are required to make the paging work.  FirstRow is always set to 1, which isn’t very interesting, but LastRow is calculated to be the value of $LastRow - $FirstRow + 1.  Variables or parameters are referred to with a preceding dollar sign, and list columns with a preceding @ sign.  So $FirstRow would be a parameter or variable called FirstRow, where @FirstRow would be the value of a list column called FirstRow.

Frankly, if you try to trace through some of what SharePoint Designer creates along these lines, it may seem like total gobbledy-gook. This is primarily due to the fact that Designer needs to be “prepared” for the other options you might choose, and also due to the fact that it needs to add in XSL for boundary conditions that you may not think of. (First rows, last rows, etc.)

Next up: <xsl:param>. A value you’ve passed into a template with <xsl:with-param>. You need to have an <xsl:param> at the top of the template for each value you expect to be passed into it.

Unlocking the Mysteries of Data View Web Part XSL Tags – Part 5 – <xsl:param>

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

Cross-posted from EndUserSharePoint.com

<xsl:param>

A value you’ve passed into a template with <xsl:with-param>. You need to have an <xsl:param> at the top of the template for each value you expect to be passed into it.

I talked in the last post about passing values into templates using <xsl:with-param>. Whenever you pass these values, you need to tell the “receiving” template to expect them. You do this by using the <xsl:param> tag.

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

  • At the top of the XSL, prior to any templates
  • At the top of the dvt_1.body template
<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>

At the top of the XSL, we see one use of <xsl:param>.  Anything which we declare at this level (outside any individual  templates) is available, or scoped, to the entire XSL section.

<xsl:param name="dvt_apos">'</xsl:param>

SharePoint Designer puts this silly little line of code in DVWPs to set up a parameter to represent the apostrophe character. Because of the highly reserved nature of this character, it can be a bear to work with, and this way you have a parameter containing it to use.

We need an <xsl:param> here for any values we’re declaring in the ParameterBindings section which we want to use in the XSL, too. So, for instance, if we declare the URL Server Variable in the ParameterBindings section: <ParameterBinding Name="URL" Location="ServerVariable(URL)" DefaultValue=""/>, then we need an <xsl:param> at the top of the XSL if we want to use the value: <xsl:param name="URL">.

In the dvt_1.body template, we can see:

<xsl:param name="Rows"/>

When the dvt_1.body template is called, Rows is being passed with <xsl:with-param>:

<br />
<xsl:call-template name="dvt_1.body"><br />
  <xsl:with-param name="Rows" select="$Rows"/><br />
</xsl:call-template><br />

We need the <xsl:param> tag to “catch” the value that is being thrown in. This “catch” idea is required for anything that we pass into a template. Any parameter which we declare inside a template is available, or scoped, only within that template.

When you want to use a parameter which you’ve “caught”, you precede the name with a dollar sign. (The same is true for <xsl:variable>, but that’s the next installment.) So in the Rows example above, you’d use the parameter as $Rows (you’ll see this parameter a lot in the XSL). In the URL example, it’d be $URL.

Next up: <xsl:variable>

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