Re: xslt to generate XSL-FO table-layout=fixed
I've been working with something similar. I should warn you that I'm a little new to both xslt and xsl-fo myself and this mini-project was my first with a table so that there might be a better way. I'm going to return to this one soon to improve it but it might give you some ideas. In our XML application we can't go by number of columns in the first row since elements might be absent (indicating a empty cell needs to be in the table). So instead we have a "description" area that has names of the columns. We use this to calculate how many elements there are and their widths. The structure of the xml is along the lines of <spreadsheet> <description> <columns> <column> ......<columns> </columns> </description> <table> <row> <foo> <bar> <foobar> </row> ... </table> </spreadsheet> XSLT- This is taken from our template that initially calls the function: <xsl:call-template name="createColumns"> <xsl:with-param name="columns" select="/spreadsheet/description/columns/column"/> <xsl:with-param name="total" select="0"/> </xsl:call-template> The following function takes a group of "columns" . The base case is the last column, for which it writes out a proportinal-column-width that is 100 minus the total percentages of what has already been processed. If not the base case, it creates a column by taking the second and third character of 1/total number of columns. (.33333333333333 becomes 33) and then calls this function with the that number added to the total and one less element in the node set. <xsl:template name="createColumns"> <xsl:param name="columns"/> <xsl:param name="total" /> <!-- if last, end this madness --> <xsl:choose> <!-- base case --> <xsl:when test="count($columns) = 1"> <xsl:element name="fo:table-column"> <xsl:attribute name="column-width"> <xsl:text>proportional-column-width(</xsl:text><xsl:value-of select="100 - $total"/><xsl:text>)</xsl:text> </xsl:attribute> </xsl:element> </xsl:when> <!-- recursive --> <xsl:otherwise> <xsl:variable name="rawpercentage"> <xsl:value-of select="1 div count(/spreadsheet/description/columns/column)"/> </xsl:variable> <xsl:variable name="width"> <xsl:value-of select="substring($rawpercentage,3,2)"/> </xsl:variable> <xsl:element name="fo:table-column"> <xsl:attribute name="column-width"> <xsl:text>proportional-column-width(</xsl:text><xsl:value-of select="$width"/><xsl:text>)</xsl:text></xsl:attribute> </xsl:element> <!-- recursive call --> <xsl:call-template name="createColumns"> <xsl:with-param name="columns" select="$columns[position() > 1]" /> <xsl:with-param name="total" select="$total + $width" /> </xsl:call-template> </xsl:otherwise> </xsl:choose> </xsl:template> This workaround was created after playing around with the columns for a while and reading through the fop mailing list as well as the archives for this one. I'm sure there are nicer and spiffer ways to do this. Also notice that it will not create columns of exact size for odd numbers (the right one will be slightly bigger). The actual xslt is a little more complex since we need to map the elements to their row placement. Probably the XML could be improved too. Jon Gorman
PURCHASE STYLUS STUDIO ONLINE TODAY!
Purchasing Stylus Studio from our online shop is Easy, Secure and Value Priced!
Download The World's Best XML IDE!
Accelerate XML development with our award-winning XML IDE - Download a free trial today!
Subscribe in XML format