tags:

views:

26

answers:

1

Trying to create a table where rows are turned into columns so that I can logically group the columns in XML. The XML s something like this:

   <root>
   <field name="field1">
     <string>field1.row1</string>
     <string>field1.row2</string>
     <string>field1.row3</string>
     <string>field1.row4</string>
   </field> 
   <field name="field2">
     <string>field2.row1</string>
     <string>field2.row2</string>
     <string>field2.row3</string>
     <string>field2.row4</string>
   </field>
   <field name="field3">
     <string>field3.row1</string>
     <string>field3.row2</string>
     <string>field3.row3</string>
     <string>field3.row4</string>
   </field>
 </root>

This means every field has numerous cells all displayed in a column, and instead of the field spanning columns, it is displayed over several rows.

I have tried to create some xsl (to no avail) to display this information as a horizontally grouped table.

Any ideas on how this could be done?

A: 

This stylesheet produces a simple XSL-FO table. It turns the field elements into columns, and the string elements into rows:

<?xml version="1.0"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:fo="http://www.w3.org/1999/XSL/Format"&gt;
    <xsl:output method="xml" indent="yes" />

    <xsl:variable name="fieldCount"  select="count(/root/field)" />
    <xsl:variable name="stringCount"  select="count(/root/field[1]/string)" />

    <xsl:template match="root">
        <fo:table-and-caption>
            <fo:table>
                <fo:table-header>
                    <fo:table-row>
                        <xsl:call-template name="header">
                            <xsl:with-param name="currentCol" select="'1'"/>
                            <xsl:with-param name="maxCols" select="$fieldCount"/>
                        </xsl:call-template>
                    </fo:table-row>
                </fo:table-header>
                <fo:table-body>
                    <xsl:call-template name="row">
                        <xsl:with-param name="currentRow" select="'1'"/>
                        <xsl:with-param name="maxRows" select="$stringCount" />
                    </xsl:call-template>
                </fo:table-body>
            </fo:table>
        </fo:table-and-caption>
    </xsl:template>

    <xsl:template name="header">
        <xsl:param name="currentCol"/>
        <xsl:param name="maxCols" />

        <fo:table-cell>
            <fo:block font-weight="bold">
                <xsl:text>Column </xsl:text>
                <xsl:value-of select="field[position()=$currentCol]/@name"/>
            </fo:block>
        </fo:table-cell>

        <xsl:if test="$currentCol &lt; $maxCols">
            <xsl:call-template name="header">
                <xsl:with-param name="currentCol" select="$currentCol+1"/>
                <xsl:with-param name="maxCols" select="$maxCols"/>
            </xsl:call-template>
        </xsl:if>
    </xsl:template>

    <xsl:template name="row">
        <xsl:param name="currentRow"/>
        <xsl:param name="maxRows" />

        <fo:table-row>
            <xsl:call-template name="cell">
                <xsl:with-param name="currentRow" select="$currentRow" />
                <xsl:with-param name="currentCol" select="'1'" />
                <xsl:with-param name="maxCols" select="$fieldCount" />
            </xsl:call-template>
        </fo:table-row>

        <xsl:if test="$currentRow &lt; $maxRows">
            <xsl:call-template name="row">
                <xsl:with-param name="currentRow" select="$currentRow+1"/>
                <xsl:with-param name="maxRows" select="$maxRows" />
            </xsl:call-template>
        </xsl:if>

    </xsl:template>

    <xsl:template name="cell">
        <xsl:param name="currentRow"/>
        <xsl:param name="currentCol"/>
        <xsl:param name="maxCols" />

        <xsl:apply-templates select="field[position()=$currentCol]/string[position()=$currentRow]"/>

        <xsl:if test="$currentCol &lt; $maxCols">
            <xsl:call-template name="cell">
                <xsl:with-param name="currentRow" select="$currentRow"/>
                <xsl:with-param name="currentCol" select="$currentCol+1" />
                <xsl:with-param name="maxCols" select="$maxCols" />
            </xsl:call-template>
        </xsl:if>
    </xsl:template>

    <xsl:template match="string">
        <fo:table-cell>
            <fo:block>
                <xsl:value-of select="."/>
            </fo:block>
        </fo:table-cell>
    </xsl:template>

</xsl:stylesheet>

Output generated from the sample XML:

<?xml version="1.0" encoding="UTF-16"?>
<fo:table-and-caption xmlns:fo="http://www.w3.org/1999/XSL/Format"&gt;
    <fo:table>
        <fo:table-header>
            <fo:table-row>
                <fo:table-cell>
                    <fo:block font-weight="bold">Column field1</fo:block>
                </fo:table-cell>
                <fo:table-cell>
                    <fo:block font-weight="bold">Column field2</fo:block>
                </fo:table-cell>
                <fo:table-cell>
                    <fo:block font-weight="bold">Column field3</fo:block>
                </fo:table-cell>
            </fo:table-row>
        </fo:table-header>
        <fo:table-body>
            <fo:table-row>
                <fo:table-cell>
                    <fo:block>field1.row1</fo:block>
                </fo:table-cell>
                <fo:table-cell>
                    <fo:block>field2.row1</fo:block>
                </fo:table-cell>
                <fo:table-cell>
                    <fo:block>field3.row1</fo:block>
                </fo:table-cell>
            </fo:table-row>
            <fo:table-row>
                <fo:table-cell>
                    <fo:block>field1.row2</fo:block>
                </fo:table-cell>
                <fo:table-cell>
                    <fo:block>field2.row2</fo:block>
                </fo:table-cell>
                <fo:table-cell>
                    <fo:block>field3.row2</fo:block>
                </fo:table-cell>
            </fo:table-row>
            <fo:table-row>
                <fo:table-cell>
                    <fo:block>field1.row3</fo:block>
                </fo:table-cell>
                <fo:table-cell>
                    <fo:block>field2.row3</fo:block>
                </fo:table-cell>
                <fo:table-cell>
                    <fo:block>field3.row3</fo:block>
                </fo:table-cell>
            </fo:table-row>
            <fo:table-row>
                <fo:table-cell>
                    <fo:block>field1.row4</fo:block>
                </fo:table-cell>
                <fo:table-cell>
                    <fo:block>field2.row4</fo:block>
                </fo:table-cell>
                <fo:table-cell>
                    <fo:block>field3.row4</fo:block>
                </fo:table-cell>
            </fo:table-row>
        </fo:table-body>
    </fo:table>
</fo:table-and-caption>
Mads Hansen