-2

There is a 5 year old question (linked below) regarding rendering a node sequence as an M x N table in XSLT. The answer works just fine and I have used it in several projects.

Rendering a node sequence as M x N table

I now have a situation where I need to have a sorted output. New items will get added to the end of the sequence, and I can't simply regenerate the XML.

It seems to me that using this code as a starting point, one would have to have the list sorted prior to calling any templates. I've not been able to come up with a solution, and hoping one of the guru's here can help.

Some additional information for clarification. This is for a SharePoint 2010 site which only supports XSLT version 1.0. I'm rendering data from lists, which can be added to, but not re-ordered without deleting and re-entering the data. Since I can't re-order the list, I'd like the output to be sorted with the XSLT.

This is the input xml;

<root>
  <CRMData>
      <Rows>
      <Row Name1="1 test customer" Title="ACC-011636"/>
      <Row Name1="7 test customer" Title="ACC-011618"/>
      <Row Name1="14 test customer" Title="ACC-011635"/>
      <Row Name1="6 test customer" Title="ACC-011610"/>
      <Row Name1="22 test customer" Title="ACC-011627"/>
      <Row Name1="12 test customer" Title="ACC-011748"/>
      <Row Name1="3 test customer" Title="ACC-011607"/>
      <Row Name1="9 test customer" Title="ACC-011628"/>
      <Row Name1="45 test customer" Title="ACC-011754"/>
      <Row Name1="16 test customer" Title="ACC-011774"/>
      <Row Name1="10 test customer" Title="ACC-011632"/>
      <Row Name1="7 test customer" Title="ACC-011606"/>
      <Row Name1="19 test customer" Title="ACC-012275"/>
      <Row Name1="59 test customer" Title="ACC-011634"/>
      <Row Name1="33 test customer" Title="NONE-001"/>
      <Row Name1="2 test customer" Title="ACC-011617"/>
      <Row Name1="64 test customer" Title="ACC-011629"/>
      <Row Name1="15 test customer" Title="ACC-011633"/>
      <Row Name1="26 test customer" Title="ACC-011612"/>
      <Row Name1="38 test customer" Title="ACC-011608"/>
      <Row Name1="21 test customer" Title="ACC-011749"/>
      <Row Name1="8 test customer" Title="ACC-011611"/>
      <Row Name1="17 test customer" Title="ACC-011613"/>
      <Row Name1="20 test customer" Title="ACC-011714"/>
      <Row Name1="4 test customer" Title="ACC-011616"/>
      <Row Name1="62 test customer" Title="ACC-011601"/>
      <Row Name1="11 test customer" Title="ACC-012918"/>
    </Rows>
  </CRMData>
  <KenData>
    <Rows>
      <Row Title="KEN-3336" Date1="12/15/2009" Date2="6/23/2014" Version="10.1" CustomerID="ACC-011636"/>
      <Row Title="KEN-3338" Date1="10/30/2006" Date2="8/9/2012" Version="8.4.5" CustomerID="ACC-011618"/>
      <Row Title="KEN-3337" Date1="2/10/2014" Date2="2/10/2014" Version="9.3" CustomerID="ACC-011635"/>
      <Row Title="Ken-3339" Date1="3/10/2010" Date2="6/13/2013" Version="10" CustomerID="ACC-011610"/>
      <Row Title="KEN-3340" Date1="11/22/2010" Date2="9/24/2014" Version="10.1" CustomerID="ACC-011627"/>
      <Row Title="KEN-3341" Date1="1/21/2013" Date2="1/30/2015" Version="10.3" CustomerID="ACC-011748"/>
      <Row Title="KEN-3342" Date1="10/1/2008" Date2="10/1/2008" Version="8.4" CustomerID="ACC-011607"/>
      <Row Title="KEN-3344" Date1="6/17/2008" Date2="6/17/2008" Version="9.2" CustomerID="ACC-011628"/>
      <Row Title="KEN-3345" Date1="12/23/2008" Date2="11/25/2014" Version="10.2" CustomerID="ACC-011754"/>
      <Row Title="KEN-3347" Date1="11/17/2010" Date2="11/17/2010" Version="8.4.5" CustomerID="ACC-011774"/>
      <Row Title="KEN-3349" Date1="Pending" Date2="Pending" Version="10.1" CustomerID="ACC-011632"/>
      <Row Title="KEN-3350" Date1="4/2/2012" Date2="1/17/2012" Version="8.4.5" CustomerID="ACC-011606"/>
      <Row Title="KEN-3351" Date1="8/10/2015" Date2="8/10/2015" Version="10.3" CustomerID="ACC-012275"/>
      <Row Title="KEN-3353" Date1="Pending" Date2="Pending" Version="9.3" CustomerID="ACC-011634"/>
      <Row Title="KEN-3346" Date1="3/7/2011" Date2="3/15/2011" Version="8.4.5" CustomerID="NONE-001"/>
      <Row Title="KEN-3354" Date1="7/2/2013" Date2="10/12/2015" Version="10.3" CustomerID="ACC-011617"/>
      <Row Title="KEN-3355" Date1="8/15/2013" Date2="8/15/2013" Version="9.3" CustomerID="ACC-011629"/>
      <Row Title="KEN-3356" Date1="8/18/2014" Date2="8/18/2014" Version="9.3" CustomerID="ACC-011633"/>
      <Row Title="KEN-3357" Date1="3/25/2003" Date2="10/18/2011" Version="8.4" CustomerID="ACC-011612"/>
      <Row Title="KEN-3358" Date1="9/15/2007" Date2="11/18/2014" Version="10.2" CustomerID="ACC-011608"/>
      <Row Title="KEN-3359" Date1="8/1/2006" Date2="6/1/2015" Version="10.3" CustomerID="ACC-011749"/>
      <Row Title="KEN-3360" Date1="9/20/2010" Date2="9/20/2010" Version="8.4" CustomerID="ACC-011611"/>
      <Row Title="KEN-3361" Date1="7/14/2014" Date2="8/5/2014" Version="10.2" CustomerID="ACC-011613"/>
      <Row Title="KEN-3362" Date1="1/20/2005" Date2="8/21/2012" Version="9.2" CustomerID="ACC-011714"/>
      <Row Title="KEN-3363" Date1="3/15/2007" Date2="4/25/2008" Version="8.4" CustomerID="ACC-011616"/>
      <Row Title="KEN-3364" Date1="7/10/2014" Date2="7/10/2014" Version="10" CustomerID="ACC-011601"/>
      <Row Title="KEN-3875" Date1="7/10/2015" Date2="7/10/2015" Version="10.3" CustomerID="ACC-012918"/>
    </Rows>
  </KenData>
  <OtherData>
    <Rows>
      <Row Title="OTH-001" CustomerID="ACC-011636" Data1="Yes" Data2="Yes" Data3="No"/>
      <Row Title="OTH-002" CustomerID="ACC-011618" Data1="No" Data2="Yes" Data3="Yes"/>
      <Row Title="OTH-003" CustomerID="ACC-011635" Data1="No" Data2="Yes" Data3="No"/>
      <Row Title="OTH-004" CustomerID="ACC-011610" Data1="Yes" Data2="Yes" Data3="Yes"/>
      <Row Title="OTH-005" CustomerID="ACC-011627" Data1="No" Data2="No" Data3="Yes"/>
      <Row Title="OTH-006" CustomerID="ACC-011748" Data1="No" Data2="Yes" Data3="Yes"/>
      <Row Title="OTH-007" CustomerID="ACC-011607" Data1="No" Data2="Yes" Data3="Yes"/>
      <Row Title="OTH-008" CustomerID="ACC-011628" Data1="No" Data2="Yes" Data3="Yes"/>
      <Row Title="OTH-009" CustomerID="ACC-011754" Data1="Yes" Data2="Yes" Data3="Yes"/>
      <Row Title="OTH-010" CustomerID="ACC-011774" Data1="No" Data2="Yes" Data3="Yes"/>
      <Row Title="OTH-011" CustomerID="ACC-011632" Data1="Yes" Data2="Yes" Data3="Yes"/>
      <Row Title="OTH-012" CustomerID="ACC-011606" Data1="No" Data2="Yes" Data3="Yes"/>
      <Row Title="OTH-013" CustomerID="ACC-012275" Data1="Yes" Data2="Yes" Data3="Yes"/>
      <Row Title="OTH-014" CustomerID="ACC-011634" Data1="No" Data2="Yes" Data3="Yes"/>
      <Row Title="OTH-015" CustomerID="NONE-001"   Data1="No" Data2="No" Data3="Yes"/>
      <Row Title="OTH-016" CustomerID="ACC-011617" Data1="Yes" Data2="No" Data3="Yes"/>
      <Row Title="OTH-017" CustomerID="ACC-011629" Data1="No" Data2="No" Data3="Yes"/>
      <Row Title="OTH-018" CustomerID="ACC-011633" Data1="No" Data2="Yes" Data3="Yes"/>
      <Row Title="OTH-019" CustomerID="ACC-011612" Data1="No" Data2="Yes" Data3="Yes"/>
      <Row Title="OTH-020" CustomerID="ACC-011608" Data1="No" Data2="Yes" Data3="No"/>
      <Row Title="OTH-021" CustomerID="ACC-011749" Data1="Yes" Data2="Yes" Data3="Yes"/>
      <Row Title="OTH-022" CustomerID="ACC-011611" Data1="No" Data2="Yes" Data3="Yes"/>
      <Row Title="OTH-023" CustomerID="ACC-011613" Data1="Yes" Data2="Yes" Data3="Yes"/>
      <Row Title="OTH-024" CustomerID="ACC-011714" Data1="No" Data2="Yes" Data3="Yes"/>
      <Row Title="OTH-025" CustomerID="ACC-011616" Data1="Yes" Data2="Yes" Data3="Yes"/>
      <Row Title="OTH-026" CustomerID="ACC-011601" Data1="No" Data2="Yes" Data3="Yes"/>
      <Row Title="OTH-027" CustomerID="ACC-012918" Data1="No" Data2="Yes" Data3="Yes"/>
    </Rows>
  </OtherData>
  <NPSData>
    <Rows>
      <Row Title="NPS-0001" CustomerID="ACC-011636" Type1="LDS" Score="4.00" Year="2014"/>
      <Row Title="NPS-0002" CustomerID="ACC-011636" Type1="LDS" Score="6.00" Year="2015"/>
      <Row Title="NPS-0003" CustomerID="ACC-011636" Type1="PS" Score="3.00" Year="2014"/>
      <Row Title="NPS-0004" CustomerID="ACC-011618" Type1="LDS" Score="7.00" Year="2014"/>
      <Row Title="NPS-0005" CustomerID="ACC-011618" Type1="LDS" Score="8.00" Year="2015"/>
      <Row Title="NPS-0006" CustomerID="ACC-011635" Type1="LDS" Score="6.00" Year="2014"/>
      <Row Title="NPS-0007" CustomerID="ACC-011635" Type1="LDS" Score="2.50" Year="2015"/>
      <Row Title="NPS-0008" CustomerID="ACC-011610" Type1="LDS" Score="7.50" Year="2014"/>
      <Row Title="NPS-0009" CustomerID="ACC-011610" Type1="LDS" Score="7.50" Year="2015"/>
      <Row Title="NPS-0010" CustomerID="ACC-011610" Type1="PS" Score="7.67" Year="2015"/>
      <Row Title="NPS-0011" CustomerID="ACC-011627" Type1="LDS" Score="5.50" Year="2014"/>
      <Row Title="NPS-0012" CustomerID="ACC-011627" Type1="LDS" Score="8.67" Year="2015"/>
      <Row Title="NPS-0013" CustomerID="ACC-011748" Type1="LDS" Score="7.00" Year="2014"/>
      <Row Title="NPS-0014" CustomerID="ACC-011748" Type1="LDS" Score="8.00" Year="2015"/>
      <Row Title="NPS-0015" CustomerID="ACC-011748" Type1="PS" Score="6.00" Year="2015"/>
      <Row Title="NPS-0016" CustomerID="ACC-011628" Type1="LDS" Score="7.00" Year="2015"/>
      <Row Title="NPS-0017" CustomerID="ACC-011754" Type1="LDS" Score="7.50" Year="2015"/>
      <Row Title="NPS-0018" CustomerID="ACC-011754" Type1="PS" Score="5.00" Year="2014"/>
      <Row Title="NPS-0019" CustomerID="ACC-011774" Type1="LDS" Score="7.50" Year="2014"/>
      <Row Title="NPS-0020" CustomerID="ACC-011606" Type1="LDS" Score="8.00" Year="2014"/>
      <Row Title="NPS-0021" CustomerID="ACC-012275" Type1="LDS" Score="8.00" Year="2014"/>
      <Row Title="NPS-0022" CustomerID="ACC-012275" Type1="LDS" Score="7.00" Year="2015"/>
      <Row Title="NPS-0023" CustomerID="ACC-011634" Type1="LDS" Score="3.67" Year="2014"/>
      <Row Title="NPS-0024" CustomerID="ACC-011617" Type1="LDS" Score="10.0" Year="2014"/>
      <Row Title="NPS-0025" CustomerID="ACC-011617" Type1="LDS" Score="10.0" Year="2015"/>
      <Row Title="NPS-0026" CustomerID="ACC-011629" Type1="LDS" Score="8.00" Year="2014"/>
      <Row Title="NPS-0027" CustomerID="ACC-011629" Type1="LDS" Score="8.00" Year="2015"/>
      <Row Title="NPS-0028" CustomerID="ACC-011633" Type1="LDS" Score="7.67" Year="2014"/>
      <Row Title="NPS-0029" CustomerID="ACC-011633" Type1="LDS" Score="7.50" Year="2015"/>
      <Row Title="NPS-0030" CustomerID="ACC-011633" Type1="PS" Score="7.00" Year="2014"/>
      <Row Title="NPS-0031" CustomerID="ACC-011612" Type1="LDS" Score="6.00" Year="2014"/>
    </Rows>
  </NPSData>
</root>

I want to be able to sort the list based on the Name1 field of CRMData.

The stylesheet I'm using is;

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

  <xsl:output method="html" indent="no"/>
  <!--<xsl:strip-space elements="*"/> SharePoint doesn't like this -->
  <xsl:decimal-format NaN=""/>
  <xsl:param name="dvt_apos">&apos;</xsl:param>
  <xsl:param name="ManualRefresh"></xsl:param>
  <xsl:variable name="dvt_1_automode">0</xsl:variable>

  <xsl:variable name="perRow" select="3" />

  <xsl:template match="/root/CRMData/Rows" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:x="http://www.w3.org/2001/XMLSchema" xmlns:d="http://schemas.microsoft.com/sharepoint/dsp" xmlns:asp="http://schemas.microsoft.com/ASPNET/20" xmlns:__designer="http://schemas.microsoft.com/WebParts/v2/DataView/designer" xmlns:SharePoint="Microsoft.SharePoint.WebControls">
    <table>
      <xsl:apply-templates
        mode   = "tr"
        select = "Row[position() mod $perRow = 1]" />
    </table>
  </xsl:template>

  <xsl:template match="Row" mode="tr">
    <tr>
      <xsl:call-template name="blank" />
      <xsl:variable name="td" select=". | following-sibling::Row[position() &lt; $perRow]" />
      <xsl:apply-templates mode="td" select="$td" />
      <xsl:if test="count($td) &lt; $perRow">
        <xsl:call-template name="filler">
          <xsl:with-param name="rest" select="$perRow - count($td)" />
        </xsl:call-template>
      </xsl:if>
      <xsl:call-template name="blank" />
    </tr>
  </xsl:template>

  <xsl:template match="Row" mode="td">
    <xsl:variable name="id" select="@Title" />
    <xsl:variable name="Kendata" select="/root/KenData/Rows/Row[@CustomerID=$id]" />
    <xsl:variable name="Otherdata" select="/root/OtherData/Rows/Row[@CustomerID=$id]" />
    <xsl:variable name="NPSdata" select="/root/NPSData/Rows/Row[@CustomerID=$id and @Type1='LDS' and @Year='2015']" />

    <xsl:variable name="bgcolor">
      <xsl:choose>
        <xsl:when test="$NPSdata/@Score &gt;'7.0'">
          <xsl:value-of select="'#00ff00'" />
        </xsl:when>
        <xsl:when test="$NPSdata/@Score &gt;'5.0'">
          <xsl:value-of select="'#ffff00'" />
        </xsl:when>
        <xsl:when test="$NPSdata/@Score &gt;'0'">
          <xsl:value-of select="'#ff0000'" />
        </xsl:when>
        <xsl:otherwise>
          <xsl:value-of select="'#ffffff'" />
        </xsl:otherwise>
      </xsl:choose>
    </xsl:variable>

    <td valign="top">
      <table frame="box" style="border-collapse: collapse">
        <tr>
          <td class="ms-rteTableOddCol-0" style="width:335px;text-align:center">
            <xsl:value-of select="@Name1"/>
          </td>
        </tr>
        <tr>
          <td class="ms-rteTableOddCol-0" style="width:335px;text-align:center;background-color:{$bgcolor}">NPS -
            <xsl:value-of select="$NPSdata/@Score"/>
          </td>
        </tr>
        <tr>
          <td class="ms-rteTableOddCol-0" style="width:335px;text-align:center">Data1 -
            <xsl:value-of select="$Otherdata/@Data1"/>
          </td>
        </tr>
        <tr>
          <td class="ms-rteTableOddCol-0" style="width:335px;text-align:center">Data2 -
            <xsl:value-of select="$Otherdata/@Data2"/>
          </td>
        </tr>
        <tr>
          <td class="ms-rteTableOddCol-0" style="width:335px;text-align:center">
            <xsl:value-of select="$Kendata/@Version"/>
-
            <xsl:value-of select="$Kendata/@Date1"/>
          </td>
        </tr>
      </table>
    </td>
  </xsl:template>

  <xsl:template name="filler">
    <xsl:param name="rest" select="0" />
    <xsl:if test="$rest">
      <xsl:call-template name="blank" />
      <xsl:call-template name="filler">
        <xsl:with-param name="rest" select="$rest - 1" />
      </xsl:call-template>
    </xsl:if>
  </xsl:template>

  <xsl:template name="blank">
    <td valign="top">
      <table style="border-collapse: collapse">
        <tr>
          <td class="ms-rteTableOddCol-0" style="width:335px"></td>
        </tr>
        <tr>
          <td class="ms-rteTableOddCol-0" style="width:335px"></td>
        </tr>
        <tr>
          <td class="ms-rteTableOddCol-0" style="width:335px"></td>
        </tr>
        <tr>
          <td class="ms-rteTableOddCol-0" style="width:335px"></td>
        </tr>
        <tr>
          <td class="ms-rteTableOddCol-0" style="width:335px"></td>
        </tr>
        <tr>
          <td class="ms-rteTableOddCol-0" style="width:335px"></td>
        </tr>
      </table>
    </td>
  </xsl:template>

</xsl:stylesheet>

This produces the out put as;

1 test customer 7 test customer 14 test customer

6 test customer 22 test customer 12 test customer

And I'd like the output sorted to produce;

1 test customer 2 test customer 3 test customer

4 test customer 5 test customer 6 test customer

Thanks in advance

Community
  • 1
  • 1
M Branham
  • 3
  • 2
  • 2
    Please clarify the statements _"need to have a sorted output"_ and _" New items will get added to the end of the sequence, and I can't simply regenerate the XML"_, preferably with sample input and desired output, so this question stands on its own. Otherwise it's likely to get downvoted and closed. – Jim Garrison Dec 02 '15 at 18:50
  • Thanks Jim, I've edited my request to provide more commentary and examples. – M Branham Dec 04 '15 at 15:51
  • This question is super unclear. There is just some much missing information about what you want. To fix you need to present one or more test cases. A test case is a pairing of a complete (no elipses) input document to a complete (no elipses) output document, plus an explanation of the rules of transformation. Cut out all the detail that is not part of the nub of the problem. Explain what parts are constant, and what are variable. For example, can it be assumed that there are always 5 attributes? or can they vary too? – Sean B. Durkin Dec 06 '15 at 07:38
  • Thanks Sean. Sorry, somewhat new here, thought what I had would stand on its own given the link to a working model. I've added a redacted set of data, and the stylesheet that produces the un-sorted output. – M Branham Dec 08 '15 at 15:05

2 Answers2

0

You can use xsl:sort and micro-pipe-lining to achieve sorted tabularisation. For example, if your input document is ...

<recordset name="resId" >
  <record n="1">B</record>
  <record n="2">C</record>
  <record n="0">A</record>
  <record n="4">E</record>
  <record n="3">D</record>  
</recordset>

... applying this XSLT 2.0 stylesheet ...

<xsl:transform
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    version="2.0">
<xsl:output method="html" version="5" encoding="UTF-8" indent="yes" />
<xsl:strip-space elements="*" />

<xsl:variable name="num-cols" select="2" />

<xsl:template match="/">
  <hmtl>
    <head>
      <title>Records in tabular format</title>
    </head>
    <body>
      <h1>Records in a <xsl:value-of select="$num-cols"/> table</h1>
      <xsl:apply-templates/>
    </body>  
  </hmtl>
</xsl:template>

<xsl:template match="recordset">
  <table>
    <thead>
      <tr>
        <xsl:for-each select="1 to $num-cols">
          <td>record</td>
        </xsl:for-each>
      </tr>    
    </thead>
    <tbody>

      <xsl:variable name="records">
        <!-- Hold the records in a variable, so we can sort them. -->
        <xsl:apply-templates select="record" mode="copy">
          <xsl:sort select="@n" data-type="number" stable="yes" />
        </xsl:apply-templates>
      </xsl:variable>

      <xsl:for-each-group select="$records/record" group-adjacent="count(preceding-sibling::*) idiv $num-cols">
        <!-- Normal tabularisation technique. Our data is already sorted. -->
        <tr>
          <xsl:apply-templates select="current-group()" />
          <xsl:for-each select="count(current-group()) + 1 to $num-cols">
            <!-- The input document is ragged. So fill in the empty cells.  -->
            <td>&#160;</td>
          </xsl:for-each>
        </tr>
      </xsl:for-each-group>
    </tbody>
  </table>
</xsl:template>

<xsl:template match="record" mode="copy">
  <xsl:copy-of select="." />
</xsl:template>

<xsl:template match="record">
  <td>
    <xsl:value-of select="." />
  </td>
</xsl:template>

</xsl:transform>

... will yield this output html page ...

<!DOCTYPE HTML>
<hmtl>
   <head>
      <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
      <title>Records in tabular format</title>
   </head>
   <body>
      <h1>Records in a 2 table</h1>
      <table>
         <thead>
            <tr>
               <td>record</td>
               <td>record</td>
            </tr>
         </thead>
         <tbody>
            <tr>
               <td>A</td>
               <td>B</td>
            </tr>
            <tr>
               <td>C</td>
               <td>D</td>
            </tr>
            <tr>
               <td>E</td>
               <td>&nbsp;</td>
            </tr>
         </tbody>
      </table>
   </body>
</hmtl>
Sean B. Durkin
  • 12,659
  • 1
  • 36
  • 65
0

Short answer: you need to do this in two passes. Sort the records first, then divide them into rows and columns.

Now, to simplify the example to the problem at hand, consider the following stylesheet:

XSLT 1.0

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:exsl="http://exslt.org/common"
extension-element-prefixes="exsl">
<xsl:output method="xml" omit-xml-declaration="yes" version="1.0" encoding="utf-8" indent="yes"/>
<xsl:strip-space elements="*"/>

<xsl:param name="columns" select="3"/>

<xsl:template match="/root">
    <!-- first pass -->
    <xsl:variable name="sorted-rows">
        <xsl:for-each select="CRMData/Rows/Row">
            <xsl:sort select="@Name1" data-type="text" order="ascending"/>
            <xsl:copy-of select="."/>
        </xsl:for-each>
    </xsl:variable>
    <!-- output -->
    <table border="1">
        <xsl:for-each select="exsl:node-set($sorted-rows)/Row[position() mod $columns = 1]" >
            <tr>
                <xsl:apply-templates select=". | following-sibling::Row[position() &lt; $columns]"/>
            </tr>
        </xsl:for-each>
    </table>
</xsl:template>

<xsl:template match="Row">
    <td>
        <xsl:value-of select="@Name1"/>
    </td>
</xsl:template>

</xsl:stylesheet>

Applied to your example input, the result here will look like this:

enter image description here

Note that this is somewhat different from what you posted as the expected output, because the records are sorted alphabetically - and therefore 19 comes before 2. I presume that is the correct order, and that your actual data does not really contain a numeric prefix. Otherwise you'd have to change the sort instruction to:

<xsl:sort select="substring-before(@Name1, ' ')" data-type="number" order="ascending"/> 

Unrelated to your question: I would suggest you use keys to get the data from the other groups of rows.

michael.hor257k
  • 113,275
  • 6
  • 33
  • 51
  • Michael, thank you very much. Works perfectly, and you are correct it is an alphabetic ordering. I just used numbers to speed up the redaction. Marked as answered. – M Branham Dec 09 '15 at 16:26