【问题标题】:Is it possible to seperate the rows in an XSL table into separate page-sequences?是否可以将 XSL 表中的行分成单独的页序列?
【发布时间】:2011-02-11 18:02:13
【问题描述】:

我是 xsl 新手,所以这可能是一个显而易见的答案。

我正在使用 FOP 从 xml 和 java 中的 xsl 样式表创建一个表。该表可以有几千行 (>50,000),因此我想减少 FOP 的内存占用以避免耗尽 Java 堆空间。

现在,我的 xsl 将整个 <fo:table-body> 元素组合成一个单独的页面序列,因此在生成表的行时永远不会回收任何内存。是否有可能以某种方式将单个或一组行分成单独的页面序列?

我知道我可以通过索引遍历元素(请参阅此 stackoverflow 答案: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>

有了这个,我在&lt;page-sequence> 标记上收到一个关于主引用的错误,但我已经尝试使用 master-reference="simpleA4" 无济于事。什么给了?

除了那个语法错误之外,还有什么看起来不对的地方?

【问题讨论】:

    标签: xml xsl-fo apache-fop


    【解决方案1】:

    它们绝对不合法。

    但是你可以关闭表格,关闭页面序列,然后使用相同的参数(减去标题)开始一个新的页面序列和一个新表格。

    这是一些伪 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>
    

    恐怕这是尽可能接近理想的解决方案。

    【讨论】:

    • 您能否提供一个小例子来说明如何实现这一点?我似乎无法掌握使用其中的表格设置循环的后勤工作。编辑:谢谢,现在我只需要弄清楚 xslt 的语法就可以让选择伪代码正常工作。
    • @pclem12 不幸的是,我错过了值得信赖的工具,但我会看看我能做些什么。
    • 谢谢,我是 xsl 的新手,如果我学得慢,请见谅
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-05-04
    • 1970-01-01
    • 2019-12-26
    • 2021-01-28
    • 2023-01-14
    • 1970-01-01
    相关资源
    最近更新 更多