Once I switched to XSLT 2.0, I was able to get cells into the variable as a node-set. Unfortunately, for reasons that are too complicated to explain here, I can't use XSLT 2.0. It's fine though, because I figured out how to do it in XSLT 1.0.
I realized that I should process the data as rows and then cells instead of just cells. I had already figured out how to calculate the number of rows, and the number of columns was static. I put a sample that I created below in case anyone else needs the solution. Please note that the sample may not be the best way to do it, and it isn't complete. I just did it as a test so that I could prove that it could be done with my real data. Here's is my XML (modified from what was above to show multiple records): <my_xml> <data_set name="Data Set 1"> <value>1</value> <value>2</value> <value>3</value> <value>4</value> <value>5</value> <value>6</value> <value>7</value> </data_set> <data_set name="Data Set 2"> <value>8</value> <value>9</value> <value>10</value> </data_set> </my_xml> Here's my XSLT snippet: <xsl:template match="/"> <fo:table-body> <xsl:for-each select="/my_xml/data_set"> <xsl:variable name="Data" select="current()"/> <xsl:variable name="Cols">5</xsl:variable> <xsl:variable name="Rows" select="ceiling(count($Data/value) div $Cols)"/> <xsl:call-template name="AddRows"> <xsl:with-param name="Data" select="$Data"/> <xsl:with-param name="Cols" select="$Cols"/> <xsl:with-param name="Rows" select="$Rows"/> <xsl:with-param name="CurrRow">1</xsl:with-param> <xsl:with-param name="CurrCell">1</xsl:with-param> </xsl:call-template> </xsl:for-each> </fo:table-body> </xsl:template> <xsl:template name="AddRows"> <xsl:param name="Data"/> <xsl:param name="Cols"/> <xsl:param name="Rows"/> <xsl:param name="CurrRow"/> <xsl:param name="CurrCell"/> <xsl:if test="$CurrRow <= $Rows"> <fo:table-row> <xsl:if test="$CurrRow=1"> <xsl:element name="fo:table-cell"> <xsl:if test="$Rows > 1"> <xsl:attribute name="number-rows-spanned"><xsl:value-of select="$Rows"/></xsl:attribute> </xsl:if> <fo:block> <xsl:value-of select="$Data/@name"/> </fo:block> </xsl:element> </xsl:if> <xsl:call-template name="AddCells"> <xsl:with-param name="Data" select="$Data"/> <xsl:with-param name="Cols" select="$Cols"/> <xsl:with-param name="CurrRow" select="$CurrRow"/> <xsl:with-param name="CurrCell" select="$CurrCell"/> </xsl:call-template> </fo:table-row> <xsl:call-template name="AddRows"> <xsl:with-param name="Data" select="$Data"/> <xsl:with-param name="Cols" select="$Cols"/> <xsl:with-param name="Rows" select="$Rows"/> <xsl:with-param name="CurrRow" select="$CurrRow+1"/> <xsl:with-param name="CurrCell" select="$CurrCell + $Cols"/> </xsl:call-template> </xsl:if> </xsl:template> <xsl:template name="AddCells"> <xsl:param name="Data"/> <xsl:param name="Cols"/> <xsl:param name="CurrRow"/> <xsl:param name="CurrCell"/> <xsl:if test="$CurrCell <= ($CurrRow * $Cols)"> <fo:table-cell> <fo:block> <xsl:choose> <xsl:when test="count($Data/value[position()=$CurrCell])=1"> <xsl:value-of select="$Data/value[position()=$CurrCell]"/> </xsl:when> <xsl:otherwise>(spacer cell)</xsl:otherwise> </xsl:choose> </fo:block> </fo:table-cell> <xsl:call-template name="AddCells"> <xsl:with-param name="Data" select="$Data"/> <xsl:with-param name="Cols" select="$Cols"/> <xsl:with-param name="CurrRow" select="$CurrRow"/> <xsl:with-param name="CurrCell" select="$CurrCell + 1"/> </xsl:call-template> </xsl:if> </xsl:template> --------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]