0

私はxslが初めてなので、これは明らかな答えかもしれません。

FOPを使用してJavaでxmlとxslスタイルシートからテーブルを作成しています。テーブルには数千行 (>50,000) が含まれる可能性があるため、FOP のメモリ フットプリントを削減して、Java ヒープ スペースの使用を回避したいと考えています。

現在、私の xsl は<fo:table-body> 要素全体を単一のページ シーケンスにグループ化しているため、テーブルの行が生成されている間にメモリがリサイクルされることはありません。個々の行またはグループの行を別々のページシーケンスに分割することは可能ですか?

インデックスで要素を反復処理できることはわかっていますが (このスタックオーバーフローの回答: Xslt - iterate nodes in chunks<fo:page-sequenceを参照)、 > 要素が > 要素内で有効であるとは思いません<fo:table

テーブル内の行を分割できない場合、行を別々のテーブルに分割する方法はありますか?

編集:提案からこれを思いついた

入力 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>

入力 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>
        <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>

これで master-reference の > タグにエラーが出るのですが、<page-sequencemaster-reference="simpleA4" にしてみましたがだめでした。何を与える?

その構文エラー以外に、これで何が間違っているように見えますか?

4

1 に答える 1

0

それらは間違いなく合法ではありません。

ただし、テーブルを閉じ、ページ シーケンスを閉じてから、同じパラメーター (ヘッダーを除く) を使用して新しいページ シーケンスと新しいテーブルを開始できます。

以下は疑似 xslt コードです。

<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>

残念ながら、これは理想的なソリューションに限りなく近いものです。

于 2011-02-11T18:41:15.887 に答える