I'm working on an XML based sitemap and ran into some sorting issues so I went back to basics for testing purposes. I've created a simple test with a class student list. This code is pretty much the same as a tutorial I found a while back and I understand the logic, it's just the sort that gives me issues. If I take out the sort, it will render the names in the order they appear in the xml. With the sort it'll grab the first name, 4th name, 7th name etc and order those. So the first time going through the for-each loop it would grab Zeke, Paige, Julie, Rachel, Bart and Martin and sort them so Bart would show up first. Then when it is at Bart, it grabs the next 2 siblings which happen to be Alex and Jenny. Then it goes to Julie and the next 2 siblings and so on and so forth. Is there anyway I can have all the names sorted properly in a table? I'd like to keep the variable of cellsPerRow so I can dynamically change this at any time.
This is my xml that I'm testing with:
<ClassList>
<Student Name="Zeke"/>
<Student Name="Barb"/>
<Student Name="Frank"/>
<Student Name="Paige"/>
<Student Name="Aaron"/>
<Student Name="Jake"/>
<Student Name="Julie"/>
<Student Name="Lisa"/>
<Student Name="Bob"/>
<Student Name="Rachel"/>
<Student Name="Johnny"/>
<Student Name="Dana"/>
<Student Name="Bart"/>
<Student Name="Alex"/>
<Student Name="Jenny"/>
<Student Name="Martin"/>
</ClassList>
My xsl is:
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:output method="html" indent="no"/>
<xsl:variable name="cellsPerRow" select="3"/>
<xsl:template match="/">
<html>
<head>
<title>Class List</title>
</head>
<body>
<table border="1" cellspacing="5" cellpadding="3" width="100px">
<xsl:apply-templates select="ClassList"/>
</table>
</body>
</html>
</xsl:template>
<xsl:template match="ClassList">
<xsl:for-each select="Student[position() mod $cellsPerRow = 1]">
<xsl:sort select="@Name" order="ascending"/>
<tr>
<xsl:apply-templates
select=".|following-sibling::Student[position() < $cellsPerRow]"/>
</tr>
</xsl:for-each>
</xsl:template>
<xsl:template match="Student">
<td align="center">
<xsl:value-of select="@Name"/></td>
<xsl:if test="(position() = last()) and (position() < $cellsPerRow)">
<xsl:call-template name="FillerCells">
<xsl:with-param name="cellCount" select="$cellsPerRow - position()"/>
</xsl:call-template>
</xsl:if>
</xsl:template>
<xsl:template name="FillerCells">
<xsl:param name="cellCount"/>
<td>#160;</td>
<xsl:if test="$cellCount > 1">
<xsl:call-template name="FillerCells">
<xsl:with-param name="cellCount" select="$cellCount - 1"/>
</xsl:call-template>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
The result I get is:
Code:
<table border="1" cellspacing="5" cellpadding="3" width="100px">
<tr>
<td>Bart</td><td>Alex</td><td>Jenny</td>
</tr>
<tr>
<td>Julie</td><td>Lisa</td><td>Bob</td>
</tr>
<tr>
<td>Martin</td><td></td><td></td>
</tr>
<tr>
<td>Paige</td><td>Aaron</td><td>Jake</td>
</tr>
<tr>
<td>Rachel</td><td>Johnny</td><td>Dana</td>
</tr>
<tr>
<td>Zeke</td><td>Barb</td><td>Frank</td>
</tr>
</table>