我真的不知道如何用英语描述我的问题,所以我希望我的例子会清楚我是什么我正在努力去做。XSL-T&XSL-FO:重组XML数据动态创建页面序列,每
比方说,我有以下XML数据:
<ROOT>
<A>
<ID>A1</ID>
<DATA>
<ENTRY>
<ENTRYID>Entry1</ENTRYID>
<ITEM1>Item1</ITEM1>
<ITEM2>Item2</ITEM2>
<ITEM3>Item3</ITEM3>
</ENTRY>
<ENTRY>
<ENTRYID>Entry2</ENTRYID>
<ITEM1>Item2_1</ITEM1>
<ITEM2>Item2_1</ITEM2>
<ITEM3>Item2_3</ITEM3>
</ENTRY>
... even more entries...
</DATA>
</A>
<A>
<ID>A2</ID>
<DATA>
<ENTRY>
<ENTRYID>Entry1</ENTRYID>
<ITEM1>foo</ITEM1>
<ITEM2>bar</ITEM2>
<ITEM3>andsoon</ITEM3>
</ENTRY>
<ENTRY>
<ENTRYID>Entry2</ENTRYID>
<ITEM1>even</ITEM1>
<ITEM2>more</ITEM2>
<ITEM3>items</ITEM3>
</ENTRY>
... even more entries...
</DATA>
</A>
<A>
.. as many A-Elements as you can think of...
</A>
</ROOT>
没有限制为A-元素有多少可以在我的XML数据,或者有多少ENTRY-元素可以是A-元素中。
所以我有一个现有的XSL-文件放在一个大的页面序列(XSL-FO)内的所有数据。我正在使用Apache FOP来处理XML和XSL。输出格式是PDF。现在,当XML数据非常大时,我遇到了内存问题。 我读过很多关于在处理大数据时调整性能和内存消耗的问题,并试图将我的数据按页面分割成一个页面序列。 我面临的问题是,我不知道如何在我的样式表中处理它们之前拆分或重构数据。现在
我的样式表中的数据匹配A和ENTRY节点和格式化为一些设计整齐的表格:
<xsl:template match="A">
... print fancy title for table with A/ID ...
<fo:table>
<fo:table-header>
... fancy table header here ...
</table-header>
<fo:table-body>
<xsl:apply-templates select="DATA/ENTRY"/>
<fo:table-row>
... do some calculating for each A and create a sum table row ...
</fo:table-row>
</fo:table-body>
</fo:table>
</xsl:template>
<xsl:template match="ENTRY">
<fo:table-row>
... print Entry data in table cells ...
</fo:table-row>
</xsl:template>
完整的表为一个A元素可以跨越数百页(最坏情况)。我知道有多少个Entry-Elements可以放入一个页面。由于表头和总表行,一个A元素的第一页和最后一页将适合较少的ENTRY元素作为它们之间的页面。 我需要将数据分成合适的块。由于我对XML文件的结构没有影响,因此我需要直接在样式表中执行此操作。
我尝试了一些东西以xsl:关键,因为他们分组数据时工作得很好,但我不知道如果这些甚至对分组的我的“特殊”的形式,如果是,这将如何携手。
所以我得到的XSL应该是这样的:
<xsl:template match="/">
<fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format">
<fo:layout-master-set>...</fo:layout-master-set>
<fo:page-sequence master-reference="{$master}">
<fo:flow flow-name="xsl-region-body" font-size="10pt">
<xsl:apply-templates select="A"/>
<xsl:apply-templates select="ENTRY elemnts for first page"/>
</fo:flow>
</fo:page-sequence>
<fo:page-sequence master-reference="{$master}">
<fo:flow flow-name="xsl-region-body" font-size="10pt">
<xsl:apply-templates select="ENTRY elemnts for pages in between"/>
</fo:flow>
</fo:page-sequence>
<fo:page-sequence master-reference="{$master}">
<fo:flow flow-name="xsl-region-body" font-size="10pt">
<xsl:apply-templates select="ENTRY elemnts for last page"/>
</fo:flow>
</fo:page-sequence>
</fo:root>
</xsl:template>
请注意,中间页序必须是在一个循环,当然可以有多于一个元素。 我不确定如何循环适用于所有页面序列的所有数据。
递归方法就像一个魅力。我只是因为认为必须循环数据而被误导。非常感谢! – Kaweoosh
我没有考虑到最后一页可能需要比中间页面更少的行。我还更新了代码,以减少XSLT中文字FO的重复,方法是为'fo:page-sequence'制作一个命名模板,该模板包含三个花式标题参数,页面表的行和总和行。单页案例提供了所有三个参数;第一页案例,标题和行;中间页面的情况下,只有行;和最后一页的情况下,行和总和。 –
再次,非常感谢! – Kaweoosh