• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Jeanne Boyarsky
  • Ron McLeod
  • Paul Clapham
  • Liutauras Vilda
Sheriffs:
  • paul wheaton
  • Rob Spoor
  • Devaka Cooray
Saloon Keepers:
  • Stephan van Hulst
  • Tim Holloway
  • Carey Brown
  • Frits Walraven
  • Tim Moores
Bartenders:
  • Mikalai Zaikin

Mulitple fo:page-sequence

 
Ranch Hand
Posts: 49
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Due to the fact that my PDF runs into 100's of pages, I get outOFMemory exception. I have already taken care of the JVM memory sizes on my machine having 512MB RAM, till this is not enough.
Based on apache's recomendation, I am trying to figure out a way by which I can use multiple page sequence. Basically, my report has the same look and feel on all pages. I can have multiple sequences in one of 2 ways:
- call for a fresh page sequence after, say every 20 records (preferable, since the data volume varies for each record).
- call for a page sequence per new page, wherein I specify that the number of records per page is, say, 5
A simplified version of my XML looks like:
<ROWSET>
<ROW>
<SSN></SSN>
<NAME></NAME>
<ADDRESS></ADDRESS>
<PHONE></PHONE>
</ROW>
</ROWSET>
Here is a very simplified version of XSL that I am currently using:
<fo age-sequence master-reference="default-master">
<fo:static-content flow-name="xsl-region-before">
---------
</fo:static-content>
<fo:static-content flow-name="xsl-region-after">
----------
</fo:static-content>
<fo:flow flow-name="xsl-region-body">
<fo:table table-layout="fixed">
<fo:table-column column-width="20mm" background-color="white"/>
<fo:table-column column-width="43mm" background-color="white"/>
<fo:table-column column-width="20mm" background-color="white"/>
<fo:table-column column-width="43mm" background-color="white"/>
<fo:table-header>
--------
</fo:table-header>
<fo:table-body>
<xsl:apply-templates select="document('AllEmployees.xml')/ROWSET/ROW">
</xsl:apply-templates>
</fo:table-body>
</fo:table>
</fo:flow>
</fo age-sequence>
<xsl:template match="ROW">
<fo:table-row keep-with-next="always">
<fo:table-cell>
<fo:block><xsl:value-of select="SSN"/></fo:block>
</fo:table-cell>
<fo:table-cell>
<fo:block><fo:block><xsl:value-of select="Name"/></fo:block>
</fo:table-cell>
<fo:table-cell padding="1.0pt">
<fo:block><xsl:value-of select="Address"/></fo:block>
</fo:table-cell>
<fo:table-cell padding="1.0pt">
<fo:block><xsl:value-of select="Phone"/></fo:block>
</fo:table-cell>
</fo:table-row>
</template>
Any help would be greatly appreciated.
 
author and deputy
Posts: 3150
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Why u r loading the AllEmployees.xml using document() function.
you can supply xml directly to FOP using -XML option.

One idea could be to preprocess your xml and break them into a group of 5 records using xslt for xml,
this is possible with xsl for-each
<ROWSET>
<break> 5 <ROW></ROW> elements</break>
<break> 5 <ROW></ROW> elements</break>
<break> 5 <ROW></ROW> elements</break>
</ROWSET>
now use a new xsl for FO which will apply a new page sequence for every break element
some thing like this
<xsl:template match="break">
<fo age-sequence master-reference="default-master">
<fo:flow flow-name="xsl-region-body">
<xsl:apply-templates/>
</fo:flow>
</fo age-sequence>
</xsl:template>
Give a try.
rgds
balaji
 
Monty Guppy
Ranch Hand
Posts: 49
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I don't have control over the XML, which is delivered to me from elsewhere. So, I can't get additional tags.
However, I have been able to make some progress, and now get one record per page. I know that using MOD and position(), I can send 5 records per page sequence, but I am not sure how to implement it in the code.
Following is the XSL for the XML noted above, which generates 1 record per page-sequence while I want it to generate 5 records per page-sequence.
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:fo="http://www.w3.org/1999/XSL/Format">

<xsl utput method="xml" encoding="UTF-8" indent="yes"/>

<xsl:template match="/">
<fo:root>
<fo:layout-master-set>
<!-- Define a body (or default) page. -->
<fo:simple-page-master master-name="default-master">
<!-- Central part of page -->
<fo:region-body/>
<fo:region-before/>
<fo:region-after/>
</fo:simple-page-master>
</fo:layout-master-set>
<xsl:apply-templates select="/ROWSET/ROW">
</xsl:apply-templates>
</fo:root>
</xsl:template>

<xsl:template match="ROW">
<!-- Page Sequence -->
<fo age-sequence master-reference="default-master">
<fo:static-content flow-name="xsl-region-before">
<fo:block>
<!-- Define header. -->
</fo:block>
</fo:static-content>
<fo:static-content flow-name="xsl-region-after">
<fo:block>
<!-- Define footer. -->
</fo:block>
</fo:static-content>
<!-- The contents of the body page
entries -->
<fo:flow flow-name="xsl-region-body">
<fo:table table-layout="fixed">
<fo:table-column column-width="20mm"/>
<fo:table-column column-width="43mm"/>
<fo:table-column column-width="20mm"/>
<fo:table-column column-width="43mm"/>
<fo:table-header>
<fo:table-row>
<fo:table-cell number-columns-spanned="4" padding="4.0pt">
<fo:block><xsl:value-of select="ROWSET/REPORT_HEADER"/></fo:block>
</fo:table-cell>
</fo:table-row>
</fo:table-header>
<fo:table-body>
<fo:table-row>
<fo:table-cell padding="1.0pt">
<fo:block text-align="right">
<fo:inline>Name:</fo:inline>
</fo:block>
</fo:table-cell>
<fo:table-cell padding="1.0pt">
<fo:block text-align="left" font-size="6pt" font-weight="normal">
<xsl:value-of select="FIRST_NAME"/></fo:block>
</fo:table-cell>
<fo:table-cell padding="1.0pt">
<fo:block text-align="right" >
<xsl:text>SSN:</xsl:text>
</fo:block>
</fo:table-cell>
<fo:table-cell padding="1.0pt">
<fo:block text-align="left" font-size="6pt" font-weight="normal">
<xsl:value-of select="SSN"/>
</fo:block>
</fo:table-cell>
</fo:table-row>
- - - - getting all other data - - - - - -
</fo:table-body>
</fo:table>
</fo:flow>
</fo age-sequence>
</xsl:template>
</xsl:stylesheet>
 
Balaji Loganathan
author and deputy
Posts: 3150
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Originally posted by Prateek Gupta:
I don't have control over the XML, which is


Prateek,
Even if it sent by someone else on a random basis,you still have control on it.All u r going to do is receive the incoming xml,group them, process them for pdf.
i guess this link will sure help you on grouping.
www.dpawson.co.uk/xsl/sect2/N4486.html
Just wondering how i received a related email tip, with files in your name. is that you ? below the main content of the email.
 
Balaji Loganathan
author and deputy
Posts: 3150
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hope you solved problem,if not get back.
 
Monty Guppy
Ranch Hand
Posts: 49
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Balaji,
Thanks to you and some others who helped me point to the right direction. I was able to write the XSL for multi-page-sequences, without altering the XML.
If you or any one else would be interested, please let me know and I would post it.\
One interesting thing that I did note is that it is better to render many pages at a time rather than necessarily one page at a time. The original problem I had was I was getting java.lang.outOfMemory. Apparently the PDF gets rendered at the end of each page sequence. So, one can increase the number of records in a page sequence such that it spans to say 50 PDF pages. Rendering 50 pages at a time (in a 2000 page PDF document that I have) is better than rendering 1 page at a time. It saved about 15% time in doing that.
Some of the other things that I did to overcome Memory problems is setting the JVM memory size and taking away "Page x of y" type of references.
Thanks
Prateek
 
Balaji Loganathan
author and deputy
Posts: 3150
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
if you dont mind,please post ur solution (xsl)here, it will sure help others.
 
Monty Guppy
Ranch Hand
Posts: 49
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Please pay special attention to:
<xsl:for-each select="ROW[position() mod 150 = 1]"> (Here I consider 150 records per sequence)
and
<xsl:for-each select="following-sibling::ROW[ position() < 150 ]"> (This is where template is applied to other 149 records)
XML:
<ROWSET>
<ROW num="1">
<SSN>100-00-2000</SSN>
<FIRST_NAME>Darren</FIRST_NAME>
<MIDDLE_NAME>S</MIDDLE_NAME>
<LAST_NAME>Adli</LAST_NAME>
<SEX>M</SEX>
<BIRTH_DATE>08/10/1955</BIRTH_DATE>
<HOME_PHONE>500-245-2000</HOME_PHONE>
<ADDR_LINE1>2422 Glenmary Avenue</ADDR_LINE1>
<CITY>New York</CITY>
<STATE>LA</STATE>
<ZIP_CD>65201</ZIP_CD>
<CLASS_DESCRIPTION>LOUISVILLE</CLASS_DESCRIPTION>
<DEPENDANTS>Lizzy Richard (Spouse)<DEPENDANTS>
</ROW>
<ROW num="2">>
.. . . .
</ROW>
XSL:
<?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:output method="xml" encoding="UTF-8" indent="yes"/>

<xsl:template match="/">
<fo:root>
<fo:layout-master-set>
<!-- Define a body (or default) page. -->
<fo:simple-page-master master-name="default-master">
<!-- Central part of page -->
<fo:region-body/>
<fo:region-before/>
<fo:region-after/>
</fo:simple-page-master>
</fo:layout-master-set>
<xsl:apply-templates select="/ROWSET">
</xsl:apply-templates>
<!--xsl:template match="/ROWSET/ROW">
<xsl:apply-templates select="ROW[position() mod 4 = 1]" />
</xsl:template-->
</fo:root>
</xsl:template>
<xsl:template name="headerFooter">
<!-- Define the contents of the header. -->
<fo:static-content flow-name="xsl-region-before">
<fo:block >
<fo:table table-layout="fixed" height="13.2mm">
<fo:table-column column-width="40mm"/>
<fo:table-column column-width="85mm"/>
<fo:table-body>
<fo:table-row>
<fo:table-cell>
<fo:block>
<fo:external-graphic
src="url('C:/Humana/Reporting/pdfgeneration/images/logo.gif')" content-height="auto" content-width="1em"/>
</fo:block>
</fo:table-cell>
<fo:table-cell background-color="white" display-align="center">
<fo:table table-layout="fixed" height="7.2mm">
<fo:table-column column-width="80mm"/>
<fo:table-body>
<fo:table-row>
<fo:table-cell>
<fo:block>
<fo:inline>
<xsl:value-of
select="REPORT_NAME"/>
</fo:inline>
</fo:block>
</fo:table-cell>
</fo:table-row>
</fo:table-body>
</fo:table>
</fo:table-cell>
</fo:table-row>
</fo:table-body>
</fo:table>
</fo:block>
</fo:static-content>
<!-- Define the contents of the footer. -->
<fo:static-content flow-name="xsl-region-after">
<fo:block>
<xsl:text>Page </xsl:text>
<fo:page-number/> of 
<!--fo:page-number-citation ref-id="{generate-id(/)}"/--></fo:block>
</fo:static-content>
</xsl:template>
<xsl:template match="ROWSET">
<xsl:for-each select="ROW[position() mod 150 = 1]">
<fo:page-sequence master-reference="default-master">
<xsl:call-template name="headerFooter"/>
<!-- Body of the page -->
<fo:flow flow-name="xsl-region-body">
<fo:table table-layout="fixed">
<fo:table-column column-width="20mm" background-color="white"/>
<fo:table-column column-width="43mm" background-color="white"/>
<fo:table-column column-width="20mm" background-color="white"/>
<fo:table-column column-width="43mm" background-color="white"/>
<fo:table-header>
<fo:table-row background-color="#CCCCCC">
<fo:table-cell number-columns-spanned="4" padding="4.0pt">
<fo:block>
<xsl:value-of select="REPORT_HEADER"/>
</fo:block>
</fo:table-cell>
</fo:table-row>
<fo:table-row background-color="white">
<fo:table-cell number-columns-spanned="4">
<fo:block> </fo:block>
</fo:table-cell>
</fo:table-row>
</fo:table-header>
<fo:table-body>
<xsl:call-template name="xyz"/>
<xsl:for-each select="following-sibling::ROW[ position() < 150 ]">
<xsl:call-template name="xyz"/>
</xsl:for-each>
</fo:table-body>
</fo:table>
</fo:flow>
</fo:page-sequence>
</xsl:for-each>
</xsl:template>

<xsl:template name="xyz">
<fo:table-row keep-with-next="always">
<fo:table-cell padding="1.0pt">
<fo:block text-align="right" font-style="italic" font-size="6pt" font-weight="normal">
<fo:inline>Name:</fo:inline>
</fo:block>
</fo:table-cell>
<fo:table-cell padding="1.0pt">
<fo:block text-align="left" font-size="6pt" font-weight="normal">
<xsl:value-of select="FIRST_NAME"/> <xsl:value-of
select="MIDDLE_NAME"/> <xsl:value-of select="LAST_NAME"/></fo:block>
</fo:table-cell>
<fo:table-cell padding="1.0pt">
<fo:block text-align="right" font-style="italic" font-size="6pt" font-weight="normal">
<xsl:text>SSN:</xsl:text>
</fo:block>
</fo:table-cell>
<fo:table-cell padding="1.0pt">
<fo:block text-align="left" font-size="6pt" font-weight="normal">
<xsl:value-of select="SSN"/>
</fo:block>
</fo:table-cell>
</fo:table-row>
- - - - getting all other data - - - - - -
</xsl:template>
</xsl:stylesheet>
 
Greenhorn
Posts: 8
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
This is a really old post - I understand.

Anyone know how to customize this solution for my environment?

My sample xsl file:



$ my sample xml file:



With the current state of this code, I get an exception at line:

<xsl:if select="ROOT/MEM-STMT/ACC/PROV[position() mod 30 = 1]">

& the exception is:

org.apache.fop.fo.FOTreeBuilder fatalError. SEVERE: java.lang.NullPointerException



Any help is immensely appreciated.
 
Ranch Hand
Posts: 734
7
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
@Kamohelo Mofokeng
For xsl:if element, the attribute is test (for node test); select? never!

 
Kamohelo Mofokeng
Greenhorn
Posts: 8
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Thanks g tsuji,

I have changed xsl:if accordingly i.e. changed select to test.

So, how do I implement Monty Guppy's example for my environment - I'm still trying create multiple page sequences because I'm running out of memory when I perform transormation for large files.

Regards
 
g tsuji
Ranch Hand
Posts: 734
7
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
If that change takes out the error, what is not working? As it is a sacre long scrpt, I would suggest you open a new thread of your own so as not to mess up other people's concern. Further, I would suggest you give more precision on what errors or expectations etc... to provide more motivation for people to read it entirely critically.
 
Kamohelo Mofokeng
Greenhorn
Posts: 8
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Thank you g tsuji for the suggestion, I have created a new thread: https://coderanch.com/t/559137/XML/XSL-FO-Multiple-Page-Sequences

 
With a little knowledge, a cast iron skillet is non-stick and lasts a lifetime.
reply
    Bookmark Topic Watch Topic
  • New Topic