When i try to render footnotes in my PDF with Apache FOP i get "java.lang.IndexOutOfBoundsException: Index: 3, Size: 3"
My Code:
<fo:footnote>
<fo:inline baseline-shift="30%" font-size="10pt">
*<xsl:number count="note" level="any" />
</fo:inline>
<fo:footnote-body>
<fo:list-block font-size="8pt" provisional-distance-between-starts="0.4cm">
<fo:list-item>
<fo:list-item-label>
<fo:block>
<fo:inline baseline-shift="super" font-size="70%">
*<xsl:number count="note" level="any"/>
</fo:inline>
</fo:block>
</fo:list-item-label>
<fo:list-item-body>
<fo:block margin-left="3mm" background-color="yellow">
<xsl:value-of select="text" />
</fo:block>
</fo:list-item-body>
</fo:list-item>
</fo:list-block>
</fo:footnote-body>
</fo:footnote>
The „text“ is quite long so i guess it doesn’t fit the space.
I Figured out that if i change the font-size from 10pt to 8pt the Error is gone. So i think it has to do something with page overflow but i dont really know what i should do against it, like just giving the footnote more space on the page?
Stacktrace:
java.lang.IndexOutOfBoundsException: Index: 3, Size: 3
at java.util.ArrayList.rangeCheck(Unknown Source)
at java.util.ArrayList.get(Unknown Source)
at org.apache.fop.layoutmgr.PageBreakingAlgorithm.getFootnoteList(PageBreakingAlgorithm.java:1166)
at org.apache.fop.layoutmgr.PageBreakingAlgorithm.getFootnoteSplit(PageBreakingAlgorithm.java:788)
at org.apache.fop.layoutmgr.PageBreakingAlgorithm.getFootnoteSplit(PageBreakingAlgorithm.java:727)
at org.apache.fop.layoutmgr.PageBreakingAlgorithm.computeDifference(PageBreakingAlgorithm.java:577)
at org.apache.fop.layoutmgr.BreakingAlgorithm.considerLegalBreak(BreakingAlgorithm.java:936)
at org.apache.fop.layoutmgr.PageBreakingAlgorithm.considerLegalBreak(PageBreakingAlgorithm.java:510)
at org.apache.fop.layoutmgr.PageBreakingAlgorithm.handlePenaltyAt(PageBreakingAlgorithm.java:405)
at org.apache.fop.layoutmgr.BreakingAlgorithm.handleElementAt(BreakingAlgorithm.java:760)
at org.apache.fop.layoutmgr.BreakingAlgorithm.findBreakingPoints(BreakingAlgorithm.java:557)
at org.apache.fop.layoutmgr.BreakingAlgorithm.findBreakingPoints(BreakingAlgorithm.java:506)
at org.apache.fop.layoutmgr.AbstractBreaker.doLayout(AbstractBreaker.java:414)
at org.apache.fop.layoutmgr.PageBreaker.doLayout(PageBreaker.java:112)
at org.apache.fop.layoutmgr.PageSequenceLayoutManager.activateLayout(PageSequenceLayoutManager.java:143)
at org.apache.fop.area.AreaTreeHandler.endPageSequence(AreaTreeHandler.java:267)
at org.apache.fop.fo.pagination.PageSequence.endOfNode(PageSequence.java:130)
at org.apache.fop.fo.FOTreeBuilder$MainFOHandler.endElement(FOTreeBuilder.java:360)
at org.apache.fop.fo.FOTreeBuilder.endElement(FOTreeBuilder.java:190)
at net.sf.saxon.event.ContentHandlerProxy.endElement(ContentHandlerProxy.java:412)
at net.sf.saxon.event.ProxyReceiver.endElement(ProxyReceiver.java:185)
at net.sf.saxon.event.SequenceNormalizer.endElement(SequenceNormalizer.java:229)
at net.sf.saxon.event.NamespaceReducer.endElement(NamespaceReducer.java:235)
at net.sf.saxon.event.ComplexContentOutputter.endElement(ComplexContentOutputter.java:559)
at net.sf.saxon.expr.instruct.ElementCreator.processLeavingTail(ElementCreator.java:355)
at net.sf.saxon.expr.instruct.ElementCreator.processLeavingTail(ElementCreator.java:299)
at net.sf.saxon.expr.instruct.Block.processLeavingTail(Block.java:735)
at net.sf.saxon.expr.instruct.TemplateRule.applyLeavingTail(TemplateRule.java:352)
at net.sf.saxon.trans.Mode.applyTemplates(Mode.java:519)
at net.sf.saxon.expr.instruct.ApplyTemplates$ApplyTemplatesPackage.processLeavingTail(ApplyTemplates.java:557)
at net.sf.saxon.trans.Mode.applyTemplates(Mode.java:438)
at net.sf.saxon.expr.instruct.ApplyTemplates$ApplyTemplatesPackage.processLeavingTail(ApplyTemplates.java:557)
at net.sf.saxon.trans.Mode.applyTemplates(Mode.java:438)
at net.sf.saxon.expr.instruct.ApplyTemplates.apply(ApplyTemplates.java:300)
at net.sf.saxon.expr.instruct.ApplyTemplates.processLeavingTail(ApplyTemplates.java:255)
at net.sf.saxon.expr.instruct.Block.processLeavingTail(Block.java:735)
at net.sf.saxon.expr.instruct.Instruction.process(Instruction.java:132)
at net.sf.saxon.expr.instruct.ElementCreator.processLeavingTail(ElementCreator.java:352)
at net.sf.saxon.expr.instruct.Copy.processLeavingTail(Copy.java:422)
at net.sf.saxon.expr.instruct.TemplateRule.applyLeavingTail(TemplateRule.java:352)
at net.sf.saxon.trans.Mode.applyTemplates(Mode.java:519)
at net.sf.saxon.trans.rules.TextOnlyCopyRuleSet.process(TextOnlyCopyRuleSet.java:71)
at net.sf.saxon.trans.Mode.applyTemplates(Mode.java:482)
at net.sf.saxon.trans.XsltController.applyTemplates(XsltController.java:733)
at net.sf.saxon.s9api.AbstractXsltTransformer.applyTemplatesToSource(AbstractXsltTransformer.java:347)
at net.sf.saxon.s9api.XsltTransformer.transform(XsltTransformer.java:338)
at net.sf.saxon.jaxp.TransformerImpl.transform(TransformerImpl.java:71)
at org.apache.fop.cli.InputHandler.transformTo(InputHandler.java:293)
at org.apache.fop.cli.InputHandler.renderTo(InputHandler.java:116)
at org.apache.fop.cli.Main.startFOP(Main.java:186)
at org.apache.fop.cli.Main.main(Main.java:217)
Related
I have xslt template that generates pdf using Apache FOP. I have problem that background image cannot be found. I have tried absolute paths, relative paths and many else, but nothing happens. Could any of you help me ?
I have tried following paths, but it did not help.
c:/Projects/demo/src/main/resources/certificate.png is absolute path
background-image="c:/Projects/demo/src/main/resources/certificate.png"
background-image="file:///c:/Projects/demo/src/main/resources/certificate.png"
background-image="certificate.png"
background-image="./certificate.png"
background-image="url(certificate.png)"
background-image="url(./certificate.png)"
background-image="url(c:/Projects/demo/src/main/resources/certificate.png)"
background-image="url(file:///c:/Projects/demo/src/main/resources/certificate.png)"
background-image="url(file:///./certificate.png)"
<fo:block-container position="absolute" height="210mm" width="297mm"
background-image="c:/Projects/demo/src/main/resources/certificate.png"
background-position="right" background-color="transparent">
<!-- Name -->
<fo:block-container absolute-position="fixed"
top="95mm">
<fo:block
letter-spacing="8px"
font-size="22pt"
color="#333333"
font-family="BrandonBlack"
text-align="center">
<xsl:value-of select="data/user"/>
</fo:block>
</fo:block-container>
<!-- Course Name -->
<fo:block-container absolute-position="fixed"
top="135mm">
<fo:block
letter-spacing="5px"
font-size="19pt"
color="#7b5f6f"
font-family="BrandonBlack"
text-align="center">
<xsl:value-of select="data/course"/>
</fo:block>
</fo:block-container>
<!-- Date -->
<fo:block-container absolute-position="fixed"
top="189mm" left="214mm">
<fo:block
letter-spacing="2px"
font-size="12pt"
color="#333333"
font-family="BrandonBlack">
<xsl:value-of select="data/date"/>
</fo:block>
</fo:block-container>
</fo:block-container>
You need to use url() and wrap the URL in single quotes, like so:
<fo:block-container background-image="url('./certificate.png')" />
I have created index page using XSLT code. The contents name are shown to index page correctly but i want to map contents according to page number for specific title.
I am getting title with their description So I have named that block as id="TOC" and given as ref-id=”TOC” but the page number is not reflecting in my title.
Title:- Title names present in Index page.
Summary:- Title content associated with page.
The below is my XSLT-2.0 sample code:
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="content_name">
<fo:block space-after="7pt" space-after.conditionality="retain" line-height="1.147" font-family="Calibri" font-size="15pt" font-weight="bold" language="FR">
<fo:inline>
<fo:leader leader-length="0pt" />
<xsl:value-of select="title"/>
<fo:page-number-citation ref-id="TOC"/>
</fo:inline>
</fo:block>
</xsl:template>
<xsl:template match="pro_list">
<fo:block space-after="15pt" space-after.conditionality="retain" line-height="1.147" font-family="Calibri" font-size="15pt" font-weight="bold" text-decoration="underline" language="FR">
<fo:inline>
<fo:leader leader-length="0pt" />
<xsl:value-of select="title" id="TOC"/>
</fo:inline>
</fo:block>
<fo:block space-after="8pt" space-after.conditionality="retain" line-height="1.147" font-family="Calibri" font-size="15pt" language="FR">
<fo:inline>
<fo:leader leader-length="0pt"/>
<xsl:value-of select="summary" disable-output-escaping="yes" />
</fo:inline>
</fo:block>
</xsl:template>
</xsl:stylesheet>
This is the output:
Contents
Title1 page no.
Title2 page no.
Title3 page no.
Suppose title1 content is associated with page2 & similar for title2-3 & title3-4, then output looks like as follows
Contents
Title1 2
Tilte2 3
Title3 4
Is there any syntax or predefined function available to do index mapping?
XML file:
<formattedEgGesamt>270.94</formattedEgGesamt>
<formattedEgGesperrt>50.00</formattedEgGesperrt>
<formattedHgGesamt>78.18</formattedHgGesamt>
<formattedHgGesperrt>4.00</formattedHgGesperrt>
In my XSL file, I declare 4 variables:
<xsl:variable name="HGGesamt">
<xsl:value-of select="format-number(/Basis/PersonenkontoDTO/formattedHgGesamt,'#.00')"/>
</xsl:variable>
<xsl:variable name="HGGesperrt">
<xsl:value-of select="format-number(/Basis/PersonenkontoDTO/formattedHgGesperrt,'#.00')"/>
</xsl:variable>
<xsl:variable name="EGGesamt">
<xsl:value-of select="format-number(/Basis/PersonenkontoDTO/formattedEgGesamt,'#.00')"/>
</xsl:variable>
<xsl:variable name="EGGesperrt">
<xsl:value-of select="format-number(/Basis/PersonenkontoDTO/formattedEgGesperrt,'#.00')"/>
</xsl:variable>
These variables are used to calculate the difference between formattedHgGesamt and formattedHgGesperrt, and formattedEgGesamt and formattedEgGesperrt.
The result should be printed.
Here's the code used to print the 2 results:
<fo:table-cell padding="3pt" display-align="center" border-style="solid" border-width="1pt" border-color="white">
<fo:block font-family="Courier" text-align="right" font-weight="bold">
<xsl:value-of select="format-number(exsl:node-set($HGGesamt)-exsl:node-set($HGGesperrt),'#.00')"/> €
</fo:block>
</fo:table-cell>
<fo:table-cell padding="3pt" display-align="center" border-style="solid" border-width="1pt" border-color="white">
<fo:block font-family="Courier" text-align="right" font-weight="bold">
<xsl:value-of select="format-number(exsl:node-set($EGGesamt)-exsl:node-set($EGGesperrt),'#.00')"/> €
</fo:block>
</fo:table-cell>
The result of the first lines of code, concerning HGGesamt and HGGesperrt are printed and the result is right.
For the EGGesamt-EGGesperrt, it only prints "NaN"
Does anybody have an idea, why?
There seems to be a non-digit character with Unicode 8203 (U+200B, zero width space) in the data of <formattedEgGesamt>270.94</formattedEgGesamt>,. after the decimal point. So that way the number computations result in NaN.
As #martin-honnen said.
There's also easier ways to get the numbers that you want, e.g.
<xsl:variable name="HGGesamt" select="/Basis/PersonenkontoDTO/formattedHgGesamt"/>
<xsl:variable name="HGGesperrt" select="/Basis/PersonenkontoDTO/formattedHgGesperrt"/>
<xsl:variable name="EGGesamt" select="/Basis/PersonenkontoDTO/formattedEgGesamt"/>
<xsl:variable name="EGGesperrt" select="/Basis/PersonenkontoDTO/formattedEgGesperrt"/>
and:
<xsl:value-of select="format-number($HGGesamt - $HGGesperrt,'#.00')"/> €
...
<xsl:value-of select="format-number($EGGesamt - $EGGesperrt,'#.00')"/> €
I am using below line to achive dynamic row height i.e the height should match with the left column .
But I also need to split the row into different cells ? When I am using simple fo:block-cell attrbutes ,I am not getting dynamic row hight . How can achive both dynamic row hieght and cells ??
<fo:table-row display-align="center">
<xsl:for-each select="xalan:distinct(Number)">
<fo:table-cell block-progression-dimension="auto" >
<fo:block-container height="10mm">
<fo:block font-size="9pt" border-right-width="0.1mm" border-right-style="solid" border-right-color="red" >
<xsl:value-of select="">
<xsl:variable name="">
<xsl:value-of select="">
</xsl:variable>
<xsl:if test="">
<xsl:value-of select=""/>
</xsl:if>
</fo:block>
</fo:block-container>
</fo:table-cell>
snapshot
Update -
I think one way that it could be done is to insert a vertical line after every cell value .Tried this , but somehow vertical line is not printing .
<fo:table-cell number-columns-spanned="2" xsl:use-attribute-sets="myBorder" display-align="center">
<fo:block font-size="10pt" text-align="center">
<fo:table>
<fo:table-body>
<fo:table-row>
<xsl:for-each select="../../../rateDetails[toGeography/sequence = $currentSequence]">
<fo:table-cell><!-- block-progression-dimension="auto" border-right-width="0.1mm" border-right-style="solid" border-right-color="black" text-align="center"> -->
<fo:block-container>
<fo:block font-size="9pt"><!-- border-right-width="0.1mm" border-right-style="solid" border-right-color="black" text-align="center"> -->
<xsl:call-template name="currencySymbol">
<xsl:with-param name="currencyCode" select="$currencyCode" />
</xsl:call-template>
<xsl:value-of select="util:formatCurrency(rate,$language,$countryCode)" />
</fo:block>
</fo:block-container>
<fo:block-container reference-orientation="90">
<fo:block>
<fo:leader leader-pattern="rule" leader-length="100%" rule-style="solid" rule-thickness="0.1mm" color="black"/>
</fo:block>
</fo:block-container>
</fo:table-cell>
</xsl:for-each>
Is there anything that I am missing for vertical line insertion .
snapshot2
If you move the border and padding properties to the fo:table-cell, the border will be the full height of the cell:
<fo:table-cell border-right="0.1mm solid red">
By setting fo:block-container/#height, you're probably finding that the text in a cell can overflow the 10mm but only the 10mm is being used to determine the row height. If you remove the fo:block-container, you should get a variable-height table row.
The new code sample makes things a bit clearer: you're using 2 nested tables.
That's another complication you don't need.
Just use 1 table.
In the first column, place all the geography codes into the first cell. It does not matter how many there are: if you have 1 geography code, the cell will be one line high. If you have 16 geography codes in this cell, the cell will automatically resize to be 3 lines high.
The rest of the row contains cells with the price information. On these cells, define the right border to generate the red vertical line.
<fo:table>
<fo:table-column column-width="..mm" column-number="1"/>
<fo:table-column column-width="..mm" column-number="2"/>
...you'll have to add some code here to add the correct number of columns to your table...
<fo:table-body>
<fo:table-row>
<fo:table-cell>
...place the code to insert the country codes here....
</fo:table-cell>
<xsl:for-each select="../../../rateDetails[toGeography/sequence = $currentSequence]">
<fo:table-cell block-progression-dimension="auto" border-right-width="0.1mm" border-right-style="solid" border-right-color="black" text-align="center">
<fo:block-container>
<fo:block font-size="9pt">
<xsl:call-template name="currencySymbol">
<xsl:with-param name="currencyCode" select="$currencyCode" />
</xsl:call-template>
<xsl:value-of select="util:formatCurrency(rate,$language,$countryCode)" />
</fo:block>
</fo:block-container>
</fo:table-cell>
</xsl:for-each>
Source XML:
<Root>
<Data>
<Code>A</Code>
<Value>10</Value>
</Data>
<Data>
<Code>A</Code>
<Value>10</Value>
</Data>
<Data>
<Code>B</Code>
<Value>10</Value>
</Data>
<Data>
<Code>A</Code>
<Value>2</Value>
</Data>
<Data>
<Code>C</Code>
<Value>10</Value>
</Data>
<Data>
<Code>A</Code>
<Value>5</Value>
</Data>
<Data>
<Code>B</Code>
<Value>4</Value>
</Data>
<Data>
<Code>A</Code>
<Value>10</Value>
</Data>
<Data>
<Code>C</Code>
<Value>10</Value>
</Data>
<Data>
<Code>B</Code>
<Value>10</Value>
</Data>
<Data>
<Code>A</Code>
<Value>10</Value>
</Data>
<Data>
<Code>C</Code>
<Value>5</Value>
</Data>
....
</Root>
XSL-FO Code:
My code(XSL-FO) contains 3 columns where each column contains the content of 'A', 'B', 'C'
<fo:table-body>
<xfd:table-row-repeat xpath="Root/Data" font-family="Arial Narrow" font-size="10pt" padding-after="0.55cm">
<xsl:if test="Code='A'">
<fo:table-cell>
<fo:block height="12pt">Value
</fo:block>
</fo:table-cell>
<fo:table-cell>
<fo:block height="12pt" border="0.1pt solid black" text-align="center">
<xsl:value-of select="Value" />
</fo:block>
</fo:table-cell>
<fo:table-cell>
<fo:block height="12pt">Points</fo:block>
</fo:table-cell>
</xsl:if>
</xfd:table-row-repeat>
</fo:table-body>
Same code for each columns to display values of 'B' & 'C'
In Table-footer i've to get these subtotal of 'A','B', 'C'
<fo:table-body>
<xfd:table-row-repeat xpath="Root/Data" font-family="Arial Narrow" font-size="10pt" padding-after="0.55cm">
<xsl:if test="Code='A'">
<fo:table-cell>
<fo:block height="12pt">SubTotal
</fo:block>
</fo:table-cell>
<fo:table-cell>
<fo:block height="12pt" border="0.1pt solid black" text-align="center">
<--Here Sum of first 15 A's. if the A's or B's or C's exceed by 15, then the table flows to 2nd Page. In that case, 1st Page table-footer shows individual subtotals of first 15 A's, 15 B's and C's. In 2nd Page, the subtotals should contain Subtotal of first 15 A's+ Succeeding A's, in the same way B's and C's -->
</fo:block>
</fo:table-cell>
<fo:table-cell>
<fo:block height="12pt">Points</fo:block>
</fo:table-cell>
</xsl:if>
</xfd:table-row-repeat>
</fo:table-body>
Here the XSL-FO code is shown for only one column(For Root/Data/Code='A'), the other 2 columns('B' & 'C') consists of same code.
Conditions in Detail:
Condition 1): when Root/Data/Code = 'A' or 'B' or 'C'
i need individual totals of 'A', 'B' and 'C' in Table-Footer individual Column.
Condition 2): inturn if individual count(Root/Data/Code) of 'A', 'B' & 'C' crosses 15. Then Page flows to 2nd Page then Table-Footer in 2nd Page needs to contains subtotal of first 15 A's + the sum of succeeding A's in the same way for B's And C's
i.e., if 20 A's, 10 B's and 25 C's are present in Source XML.
In 1st Page, Table-Footer
SubtotalI(Value of 15 A's)=
SubtotalII(Value 10 B's)=
SubtotalIII(Value 15 C's)=
In 2nd Page, Table-Footer
SubtotalI(15 A's+ next 5 A's)=
SubtotalII(Value 10 B's)= <!--No Change as count of B's is less than 15 -->
SubtotalIII(15 C's + next 10 C's)=
I'm trying this logic using xsl:key by grouping through Code tag for evaluating sum of 'A', 'B' and 'C'. As i'm new to XSLT i'm finding it too difficult to solve this logic using xsl:key. Can anyone help in solving this logic?
Thanks in Advance
There are several difficulties with what you try to achieve. Calculating subtotals at a given point is easiest actually. You just need the preceding axis and a sum to calculate it:
sum(preceding::Value[../Code = 'A'])
To include the current value as well, use the union operator like this:
sum(Value[../Code = 'A'] | preceding::Value[../Code = 'A'])
A bigger difficulty is to show a different table 'footer' on each page. Headers and footers are repeated on pages automatically, but the contents is the same across all pages which the table spans. The only solution I see is to break the table yourself, adding a different table footer each time.
By far the easiest way is to just take a fixed number of Data elements at a time, and displaying those in a separate table. You can loop through A, B and C types in one for-each, giving each value a separate row. That way the table always has the same number of rows. You can experiment with the number you can include to determine how many fit on one page.
The following code returns a table with the first 10 Data values. A, B and C values are positioned straight under each other, but you could position them left, middle, and right respectively if you like. At the bottom of the table three rows are added with subtotals for A, B and C.
<?xml version="1.0" encoding="utf-8"?>
<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="global">
<fo:region-body/>
</fo:simple-page-master>
</fo:layout-master-set>
<fo:page-sequence master-reference="global">
<fo:flow flow-name="xsl-region-body">
<fo:block>
<fo:table table-layout="fixed" width="150mm" border-style="solid">
<fo:table-column column-width="50mm"/>
<fo:table-column column-width="50mm"/>
<fo:table-column column-width="50mm"/>
<fo:table-body font-size="7pt">
<xsl:for-each select="/Root/Data[10 >= position()]">
<fo:table-row border-style="solid">
<fo:table-cell>
<fo:block height="12pt">
<xsl:value-of select="Code" />
</fo:block>
</fo:table-cell>
<fo:table-cell>
<fo:block height="12pt" border="0.1pt solid black" text-align="center">
<xsl:value-of select="Value" />
</fo:block>
</fo:table-cell>
<fo:table-cell>
<fo:block height="12pt">Points</fo:block>
</fo:table-cell>
</fo:table-row>
<xsl:if test="position() = last()">
<fo:table-row border-style="solid">
<fo:table-cell>
<fo:block height="12pt">Subtotal A</fo:block>
</fo:table-cell>
<fo:table-cell>
<fo:block height="12pt" border="0.1pt solid black" text-align="center">
<xsl:value-of select="sum(preceding::Value[../Code = 'A'] | Value[../Code = 'A'])" />
</fo:block>
</fo:table-cell>
<fo:table-cell>
<fo:block height="12pt">Points</fo:block>
</fo:table-cell>
</fo:table-row>
<fo:table-row border-style="solid">
<fo:table-cell>
<fo:block height="12pt">Subtotal B</fo:block>
</fo:table-cell>
<fo:table-cell>
<fo:block height="12pt" border="0.1pt solid black" text-align="center">
<xsl:value-of select="sum(preceding::Value[../Code = 'B'] | Value[../Code = 'B'])" />
</fo:block>
</fo:table-cell>
<fo:table-cell>
<fo:block height="12pt">Points</fo:block>
</fo:table-cell>
</fo:table-row>
<fo:table-row border-style="solid">
<fo:table-cell>
<fo:block height="12pt">Subtotal C</fo:block>
</fo:table-cell>
<fo:table-cell>
<fo:block height="12pt" border="0.1pt solid black" text-align="center">
<xsl:value-of select="sum(preceding::Value[../Code = 'C'] | Value[../Code = 'C'])" />
</fo:block>
</fo:table-cell>
<fo:table-cell>
<fo:block height="12pt">Points</fo:block>
</fo:table-cell>
</fo:table-row>
</xsl:if>
</xsl:for-each>
</fo:table-body>
</fo:table>
</fo:block>
</fo:flow>
</fo:page-sequence>
</fo:root>
</xsl:template>
</xsl:stylesheet>
You still need something to determine how many tables of n Data items you would need, and then do some recursive calls to output all of them. Hope this is sufficient for the moment to get you going again!
PS: I noticed you are using xfd prefix. That looks like you are working with the XF Designer from Ecrion. I am not very familiar with it. The above code is a plain XSLT 1.0 solution. Not sure it works in XF Designer, please let me know..