'Render table row vertically in XSL FO
Is there any way to specify vertical row direction in XSL FO. If not, workaround is also fine. I want to achieve something like this:
| C1 | r1-c1 | r2-c1 |
|---|---|---|
| C2 | r1-c2 | r2-c2 |
| C3 | r1-c3 | r2-c3 |
| .. | .. | .. |
Solution 1:[1]
No, or not easily or automatically. Tables are defined to be "row-primary" (see https://www.w3.org/TR/xsl11/#fo_table).
You could possibly format an fo:table the way that you show by doing convoluted things with reference-orientation and writing-mode, but it would be fragile and probably wouldn't work with FOP.
A less fragile way would be to use XSLT to rearrange the table so that you write your XML as a 'column-primary' table and have the XSLT flip the table and generate row-primary fo:table-row and fo:table-cell that are in the correct sequence to produce the table that you want. You would, however, have to be careful about table cells that span multiple rows or columns.
Solution 2:[2]
To give an example on how to do this in xslt:
Given this source:
<?xml-stylesheet type="text/xsl" href="xsl.xsl"?>
<table>
<thead>
<row>
<entry>C1</entry>
<entry>C2</entry>
<entry>C3</entry>
</row>
</thead>
<tbody>
<row>
<entry>r1-c1</entry>
<entry>r1-c2</entry>
<entry>r1-c3</entry>
</row>
<row>
<entry>r2-c1</entry>
<entry>r2-c2</entry>
<entry>r2-c3</entry>
</row>
</tbody>
</table>
And this xslt:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:fo="http://www.w3.org/1999/XSL/Format" >
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="table">
<fo:table>
<xsl:apply-templates select="tbody"/>
</fo:table>
</xsl:template>
<xsl:template match="tbody">
<!-- Since we use the header elements as context we store the current rows in a varable for quicker later use -->
<xsl:variable name="bodyrows" select="row"/>
<fo:table-body>
<xsl:for-each select="parent::table/thead/row/entry">
<xsl:variable name="position" select="position()"/>
<fo:table-row>
<xsl:apply-templates select="."/>
<xsl:apply-templates select="$bodyrows/entry[$position]"/>
</fo:table-row>
</xsl:for-each>
</fo:table-body>
</xsl:template>
<xsl:template match="entry">
<fo:table-cell>
<xsl:apply-templates select="." mode="font-weight"/>
<xsl:apply-templates/>
</fo:table-cell>
</xsl:template>
<xsl:template match="thead/row/entry" mode="font-weight">
<xsl:attribute name="font-weight" select="'bold'"/>
</xsl:template>
<xsl:template match="tbody/row/entry" mode="font-weight"/>
</xsl:stylesheet>
Will result in this fo-xml:
<?xml version="1.0" encoding="UTF-8"?>
<fo:table xmlns:fo="http://www.w3.org/1999/XSL/Format">
<fo:table-body>
<fo:table-row>
<fo:table-cell font-weight="bold">C1</fo:table-cell>
<fo:table-cell>r1-c1</fo:table-cell>
<fo:table-cell>r2-c1</fo:table-cell>
</fo:table-row>
<fo:table-row>
<fo:table-cell font-weight="bold">C2</fo:table-cell>
<fo:table-cell>r1-c2</fo:table-cell>
<fo:table-cell>r2-c2</fo:table-cell>
</fo:table-row>
<fo:table-row>
<fo:table-cell font-weight="bold">C3</fo:table-cell>
<fo:table-cell>r1-c3</fo:table-cell>
<fo:table-cell>r2-c3</fo:table-cell>
</fo:table-row>
</fo:table-body>
</fo:table>
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Tony Graham |
| Solution 2 |
