0
votes

I need some help with a template in xsl-fo to generate a pdf from xml data.

My issue is that I need to make a table that gets only one item(node) of many.

For exaple I might have an xml that looks like this

<CollectionOfItems>
<items>
<title ID="someid" location="somelocation" price="someprice"/>
<title ID="someid" location="somelocation" price="someprice"/>
<title ID="someid" location="somelocation" price="someprice"/>
</items>
<items>
<title ID="someid" location="somelocation" price="someprice"/>
<title ID="someid" location="somelocation" price="someprice"/>
<title ID="someid" location="somelocation" price="someprice"/>
</items>
</items>
<title ID="someid" location="somelocation" price="someprice"/>
<title ID="someid" location="somelocation" price="someprice"/>
<title ID="someid" location="somelocation" price="someprice"/>
<title ID="someid" location="somelocation" price="someprice"/>
<title ID="someid" location="somelocation" price="someprice"/>
<title ID="someid" location="somelocation" price="someprice"/>
</items>
</CollectionOfItems>

Each "items" nodes need to be in a separate table...so I made a table in xsl-fo table that looks like this

<fo:table width="100%" border-style="outset" border-width="2pt" background-repeat="no-repeat">
<fo:table-column/>
<fo:table-column/>
<fo:table-column/>
<fo:table-body>
    <xsl:for-each select="/Items/item/DataModification/Form/Tab/ModControl/Value/CompetenceConfig/Chapters/Chapter">
        <xsl:variable name="Chapter" select="."/>
        <fo:table-row>
            <fo:table-cell border-style="inset" border-width="2pt" padding="2pt" background-repeat="repeat" display-align="center">
                <fo:block>
                    <xsl:value-of select="@ID"/>
                </fo:block>
            </fo:table-cell>
            <fo:table-cell border-style="inset" border-width="2pt" padding="2pt" background-repeat="repeat" display-align="center">
                <fo:block>
                    <xsl:value-of select="@location"/>
                </fo:block>
            </fo:table-cell>
            <fo:table-cell border-style="inset" border-width="2pt" padding="2pt" background-repeat="repeat" display-align="center">
            <fo:block>
                <xsl:value-of select="@price"/>
            </fo:block>
            </fo:table-cell>
        </fo:table-row>
    </xsl:for-each>
</fo:table-body>

This kinda works but instead of getting for example one "items" node with the items inside for each table I get 3 tables with the 3 "items" nodes that look the same. How can I show the first "nodes" item in the first table, the second "items" node in the second table and so on? I would really appreciate any help on this. I have been trying to solve this for days and I am new to xsl-fo.

Thanks a lot!

1
Showing us this in your XSL: /Items/item/DataModification/Form/Tab/ModControl/Value/CompetenceConfig/Chapters/Chapter And then providing an XML that does not even come close to having that structure (nor the template above it) is worthless. No one can guess at the context at which you are working. - Kevin Brown
So for you to explain further and based on your input ... are you saying you want six tables? The first would have 3 rows, the second three rows. the third three rows, the forth, fifth and six one row each? Is that what you are asking? - Kevin Brown
Sorry Kevin, I meant to change that to /CollectionOfItems/items/title. - jcolon
I want 3 tables, in each table i should have what is inside the "items" node - jcolon
eg. the first "items" node should be in the first table. so the first table would have 3 rows, the second table should have 3 rows and the third 6 rows. All of them should have 3 columns (ID, location and price) - jcolon

1 Answers

1
votes

What about something like this? Not knowing what else you have and correcting an error you have in your XML ....

    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fo="http://www.w3.org/1999/XSL/Format">
    <xsl:template match="/">
        <fo:root>
            <fo:layout-master-set>
                <fo:simple-page-master master-name="page" page-width="8.5in" page-height="11in" margin-top="0.5in" margin-bottom="0.5in" margin-left="0.5in" margin-right="0.5in">
                    <fo:region-body region-name="body" margin-top="0.5in" margin-bottom="0.5in" margin-left="0.5in" margin-right="0.5in"/>
                </fo:simple-page-master>
            </fo:layout-master-set>
            <fo:page-sequence master-reference="page">
                <fo:flow flow-name="body">
                    <xsl:apply-templates/>
                </fo:flow>
            </fo:page-sequence>
        </fo:root>
    </xsl:template>
    <xsl:template match="items">
        <fo:block space-before="6pt" border-top="3pt solid green">
            <fo:table>
                <fo:table-body>
                    <xsl:apply-templates/>
                </fo:table-body>
            </fo:table>
        </fo:block>
    </xsl:template>
    <xsl:template match="title">
        <fo:table-row>
            <xsl:apply-templates select="@*"/>
        </fo:table-row>
    </xsl:template>
    <xsl:template match="@ID | @location | @price">
        <fo:table-cell border="1pt solid black">
            <fo:block>
                <xsl:value-of select="."/>
            </fo:block>
        </fo:table-cell>
    </xsl:template>
</xsl:stylesheet>

Yields this:

enter image description here

This has templates that creates a table for each "items" tag, a row for each "title" tag and a cell for each of the attributes in the "title" tag. I believe that is what you want.