Xslt - iterate nodes in chunks

只谈情不闲聊 提交于 2019-12-20 04:13:15

问题


I have an existing xslt script which creates a PDF with FOP, problem is that its running out of memory when doing apply-template on a specific nodetype when the node count exceeds a certain limit. In order to fix the memory issue I need to break up the result derived from that template call into several <fo:page-sequence>, but I dont want a page-sequence for each node, more like for each 100 node.

My first thought was to use position() and simply add new sequence tags every 100th, but as xslt needs to be well formed I cant have open tags like that.

So, my question is what would be the best alternative to iterate all nodes of a specific type in chunks of 100?

Example of how the XML source looks like

 <var ID="V1"><subnodes/></var>  
 ..
 <var ID="V1000"><subnodes/></var>

Currently processed with

<fo:page-sequence>
  <xsl:apply-templates select="ns:var"/>
</fo:page-sequence>

The wanted FOP XML result would be something which created several page-sequences with (for example) 100 of processed var nodes in each instead of having the result of all 1000 in óne page-sequence.

Current result

<fo:page-sequence>
  <formatted V1>
  ..
  <formatted V1000>
</fo:page-sequence>

Wanted result

<fo:page-sequence>
   <formatted V1>
    ..
   <formatted V100>
</fo:page-sequence>

<fo:page-sequence>
  <formatted V101>
   ..
  <formatted V200>
 </fo:page-sequence>

..

<fo:page-sequence>
  <formatted V901>
   ..
  <formatted V1000>
</fo:page-sequence>   

回答1:


Edit: Sorry for typo. Miss node test after following-sibling axis

With this input:

<root>
    <var ID="V1">
        <subnodes/>
    </var>
    <var ID="V2">
        <subnodes/>
    </var>
    <var ID="V3">
        <subnodes/>
    </var>
    <var ID="V4">
        <subnodes/>
    </var>
    <var ID="V5">
        <subnodes/>
    </var>
    <var ID="V6">
        <subnodes/>
    </var>
    <var ID="V7">
        <subnodes/>
    </var>
    <var ID="V8">
        <subnodes/>
    </var>
</root>

This styleshet:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fo="http://www.w3.org/1999/XSL/Format">
    <xsl:template match="root">
        <xsl:copy>
            <xsl:copy-of select="document('')/*/namespace::*[name()!='xsl']"/>
            <!-- Forget above. It's just to prettify namespace fixup -->
            <xsl:for-each select="var[position() mod 3 = 1]">
                <fo:page-sequence>
                    <xsl:apply-templates
             select=".|following-sibling::var[3 > position()]"/>
                </fo:page-sequence>
            </xsl:for-each>
        </xsl:copy>
    </xsl:template>
    <xsl:template match="var">
        <formatted id="{@ID}"/>
    </xsl:template>
</xsl:stylesheet>

Output:

<root xmlns:fo="http://www.w3.org/1999/XSL/Format">
    <fo:page-sequence>
        <formatted id="V1" />
        <formatted id="V2" />
        <formatted id="V3" />
    </fo:page-sequence>
    <fo:page-sequence>
        <formatted id="V4" />
        <formatted id="V5" />
        <formatted id="V6" />
    </fo:page-sequence>
    <fo:page-sequence>
        <formatted id="V7" />
        <formatted id="V8" />
    </fo:page-sequence>
</root>


来源:https://stackoverflow.com/questions/3521102/xslt-iterate-nodes-in-chunks

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!