开发者

Is it possible to seperate the rows in an XSL table into separate page-sequences?

I'm new to xsl, so this might be an obvious answer.

I'm creating a table from xml and an xsl stylesheet in java using FOP. The table can have several thousand rows (>50,000) so I want to reduce the memory footprint of FOP to avoid using up the Java heap space.

Right now, my xsl groups the entire <fo:table-body> element into a single page-sequence so there is never any memory recycled while the rows of the table are being generated. Is it possible to somehow break individual or groups of rows into separate page-sequences?

I know I can iterate through elements by the index (see this stackoverflow answer: Xslt - iterate nodes in chunks), but I don't think <fo:page-sequence> elements are legal inside of a <fo:table> element.

If it's not possible to break up rows within a table, is there a way I could break up the rows into separate tables?

edit: I've come up with this from the suggestion

input xml:

<?xml version="1.0" encoding="UTF-8"?>
<table title="sample">
<headers>
    <column>title1</column>
    <column>title2</column>
    <column>title3</column>
    <column>title4</column>
    <column>title5</column>
    <column>title6</column>
</headers>
<row>
    <column>0</column>
    <column>ABC</column>
    <column>0</column>
    <column>Claim Appeal</column>
    <column>asldkjf98aet24</column>
    <column>897123947623</column>
</row>
<row>
     ...
</row>
    ...
</table>

input xsl:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.1" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:fo="http://www.w3.org/1999/XSL/Format" exclude-result-prefixes="fo">
 <xsl:output method="xml" version="1.0" omit-xml-declaration="no"
indent="yes"/>
<xsl:template match="table">
<xsl:variable name="startRow" select="0"/>
<fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format">
<fo:layout-master-set>
<fo:simple-page-master master-name="simpleA4" page-height="29.7cm"
page-width="22cm" margin-top="2cm" margin-bottom="2cm"
margin-left="1.5cm" margin-right="1.5cm">
<fo:region-body/>
</fo:simple-page-master>
</fo:layout-master-set> 
<xsl:param name="startRow"/>
<fo:page-sequence>  
<fo:table>
      <xsl:if test="$startRow = 0">
  <fo:table-header>
        <开发者_StackOverflow社区fo:table-row font-weight="bold">
                <xsl:apply-templates select="headers"/>
        </fo:table-row>
  </fo:table-header>
      </xsl:if>
      <xsl:foreach select="row[position() &gt; $startRow &amp;&amp;
position() &lt; 54]">
          <!-- call row rendering template -->
          <fo:table-body>
            <xsl:apply-templates select="row"/>
          </fo:table-body>
      </xsl:foreach>    
   </fo:table>
   </fo:page-sequence>   
   </fo:root>       
    <xsl:if test="$startRow &lt; 100000">
       <xsl:apply-templates select=".">
          <xsl:with-param name="startRow" select="$startRow + 54"/> 
       </xsl:apply-templates>
    </xsl:if>
    <xsl:template match="headers">
        <xsl:for-each select="column">
            <fo:table-cell>
                <fo:block>
                    <xsl:value-of select="."/>
                </fo:block>
            </fo:table-cell>
        </xsl:for-each>
    </xsl:template>     
    <xsl:template match="row">
    <fo:table-row>
        <xsl:for-each select="column">
        <fo:table-cell>
            <fo:block>
                <xsl:value-of select="."/>
            </fo:block>
        </fo:table-cell>
    </xsl:for-each>
    </fo:table-row>
    </xsl:template>
</xsl:template>
</xsl:stylesheet>

With this, I get an error on the <page-sequence> tag about the master-reference, but I've tried it with master-reference="simpleA4" to no avail. What gives?

Aside from that syntax error, what else looks wrong in this?


They are definitely not legal.

But you can close the table, close the page sequence, then start a new page sequence and a new table with the same parameters (minus the header).

Here's some pseudo xslt code:

<xsl:template match="myTableElement">
   <xsl:param name="startRow"/>
   <fo:page-sequence>   <!-- you may only want to put this in if this isn't the first chunk -->
   <fo:table>
      <xsl:if test="$startRow = 0">
          <!-- render header -->
      </xsl:if>
      <xsl:foreach select="elements between between startRow and startRow+50000">
          <!-- call row rendering template -->
      </xsl:foreach>

   </fo:table>
   </fo:page-sequence>       

    <xsl:if test="there are unrendered elements left">
       <xsl:apply-templates select=".">
          <xsl:with-param name="startRow" select="$startRow + 50000"/> 
       </xsl:apply-templates>
    </xsl:if>
</xsl:template>

This is, I'm afraid, as close as you can get to the ideal solution.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜