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

5 minute read

Cross-posted from EndUserSharePoint.com

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

Once you have a rowset like the $Rows I talked about in the prior article about <xsl:variable>, you’ll want to do something with it. If you’ve ever used a report writer or created reports in an application like Microsoft Access, the basic constructs here may look a little familiar. Basically, you will want to have some sort of header and/or footer information (perhaps at multiple grouping levels) and then you’ll want to show some information from the detail rows. What you show in the detail rows generally comes from the items in the rowset, which we’ve defined as $Rows. (I’ll forego carrying forward my $Bob or $Strawberry_Jam examples to avoid confusion.)

Once again, let’s look at the basic example which I’ve been using in this series. (I keep including it just to make it simpler than flipping back and forth. I’m not fond of flipping back and forth.)

<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 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>
        <th nowrap="nowrap">Title</th>
      <xsl:call-template name="dvt_1.body">
        <xsl:with-param name="Rows" select="$Rows"/>

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

  <xsl:template name="dvt_1.rowview">
      <xsl:if test="position() mod 2 = 1">
        <xsl:attribute name="class">ms-alternating</xsl:attribute>
      <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>
        <xsl:value-of select="@Title"/>

In the dvt_1 template, we set up the rowset variable, $Rows, and start outputting the TABLE which will contain the DVWP output. The next thing within the TABLE is a table row (TR) which contains a single table header cell (TH) with the text “Title”, which will be the header for the Title column. (Ignore the $dvt_1_automode stuff for now. I’ll get to things like that in a post at the end of this series.)

Next we call the dvt_1.body template. As I’ve mentioned before, the dvt_1.body template is generally where we’ll output summary information about the rowset, either before or after displaying the detail rows, depending on our requirements. Here we aren’t doing anything at the summary level, but we are calling dvt_1.rowview within an <xsl:for-each>.

What this does for us is to iterate over the set of rows, effectively calling dvt_1.rowview once for each list item in $Rows:

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

<xsl:for-each> only needs to have the select value, which should represent an XSL nodeset, or what I’ve been calling a rowset. (Yes, I probably use too many of these terms interchangeably. It comes from working with too many languages over the years and at the same time.)

Inside the <xsl:for-each> is also where you do any sorting with the <xsl:sort> tag. (You guessed it, that’s for the next article.)

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

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


Have a thought or opinion?