Можно ли разделить строки в таблице XSL на отдельные последовательности страниц? - PullRequest
0 голосов
/ 11 февраля 2011

Я новичок в xsl, так что это может быть очевидным ответом.

Я создаю таблицу из xml и таблицу стилей xsl в java, используя FOP. В таблице может быть несколько тысяч строк (> 50 000), поэтому я хочу уменьшить объем занимаемой памяти FOP, чтобы избежать использования пространства кучи Java.

Прямо сейчас, мой xsl группирует весь элемент <fo:table-body> в одну последовательность страниц, поэтому при генерировании строк таблицы никогда не перезаписывается память. Можно ли как-то разбить отдельные или группы строк на отдельные последовательности страниц?

Я знаю, что могу перебирать элементы по индексу (см. Этот ответ stackoverflow: Xslt - перебирать узлы в чанах ), но я не думаю, что элементы <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>

При этом я получаю сообщение об ошибке в теге <page-sequence> master-reference, но я пробовал его с master-reference = "simpleA4", но безрезультатно. Что дает?

Помимо этой синтаксической ошибки, что еще выглядит неправильно в этом?

1 Ответ

0 голосов
/ 11 февраля 2011

Они определенно не являются законными.

Но вы можете закрыть таблицу, закрыть последовательность страниц, затем запустить новую последовательность страниц и новую таблицу с теми же параметрами (за исключением заголовка).

Вот некоторый псевдо-код 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>

Боюсь, это как можно ближе к идеальному решению.

...