我真的不知道如何用英語描述我的問題,所以我希望我的例子會清楚我是什麼我正在努力去做。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