Vin*_*sal 5 xml xslt xsl-fo apache-fop
我遇到的问题的淡化版本就是这个.对于XML文件,例如:
<?xml version="1.0" encoding="UTF-8"?>
<items>
<item cols="1">Item 1</item>
<item cols="1">Item 2</item>
<item cols="1">Item 3</item>
<item cols="1">Item 4</item>
<item cols="1">Item 5</item>
<item cols="1">Item 6</item>
<item cols="1">Item 7</item>
<item cols="1">Item 8</item>
<item cols="1">Item 9</item>
<item cols="2">Item 10</item>
<item cols="1">Item 11</item>
<item cols="1">Item 12</item>
<item cols="1">Item 13</item>
<item cols="1">Item 14</item>
<item cols="1">Item 15</item>
<item cols="1">Item 16</item>
<item cols="1">Item 17</item>
<item cols="1">Item 18</item>
</items>
Run Code Online (Sandbox Code Playgroud)
我需要能够在单个列页面布局中打印'具有'cols = 1'的项目,以及在双列页面布局中打印'cols = 2'的项目.必须保留物品的顺序.具有相同@cols值的所有连续'项目需要显示为连续流.每次@cols值改变时,我都需要打破一个新页面并根据需要更改布局.
我正在做这样的事情:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:fo="http://www.w3.org/1999/XSL/Format">
<xsl:strip-space elements="*"/>
<xsl:template match="/">
<fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format">
<fo:layout-master-set>
<fo:simple-page-master master-name="one-column-page-master">
<fo:region-body margin-top="3cm" region-name="body" column-count="1"/>
</fo:simple-page-master>
<fo:simple-page-master master-name="two-column-page-master">
<fo:region-body margin-top="3cm" region-name="body" column-count="2"/>
<fo:region-before region-name="header" extent="2cm"/>
</fo:simple-page-master>
<fo:page-sequence-master master-name="one-column-page">
<fo:repeatable-page-master-reference master-reference="one-column-page-master"/>
</fo:page-sequence-master>
<fo:page-sequence-master master-name="two-column-page">
<fo:repeatable-page-master-reference master-reference="two-column-page-master"/>
</fo:page-sequence-master>
</fo:layout-master-set>
<xsl:for-each select="//item">
<xsl:choose>
<xsl:when test="@cols = preceding-sibling::item[1]/@cols">
<!--cols value hasn't changed, don't create a new page-sequence-->
<!--But we cannot directly add fo:flow as the child of fo:root! -->
<xsl:call-template name="itemtemplate"/>
</xsl:when>
<xsl:otherwise>
<xsl:choose>
<xsl:when test="@cols = 1">
<fo:page-sequence master-reference="one-column-page">
<xsl:call-template name="itemtemplate"/>
</fo:page-sequence>
</xsl:when>
<xsl:otherwise>
<fo:page-sequence master-reference="two-column-page">
<xsl:call-template name="itemtemplate"/>
</fo:page-sequence>
</xsl:otherwise>
</xsl:choose>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each>
</fo:root>
</xsl:template>
<xsl:template name="itemtemplate">
<fo:flow flow-name="body">
<fo:block margin-bottom="5cm">
<xsl:apply-templates/>
</fo:block>
</fo:flow>
</xsl:template>
</xsl:stylesheet>
Run Code Online (Sandbox Code Playgroud)
但当然,问题是我要么在样式表中包含<fo:page-sequence ..>,要么不能,我不能'动态'决定根据音符属性加入一个.(除非我有一个首先动态创建样式表的元程序,但我希望只使用简单的静态样式表来实现这一点).
这是一个使用xsl:for-each-groupwith的 XSLT 2.0 解决方案group-adjacent:
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:fo="http://www.w3.org/1999/XSL/Format">
<xsl:strip-space elements="*"/>
<xsl:output indent="yes"/>
<xsl:template match="/">
<fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format">
<fo:layout-master-set>
<fo:simple-page-master master-name="one-column-page-master">
<fo:region-body margin-top="3cm" region-name="body"
column-count="1"/>
</fo:simple-page-master>
<fo:simple-page-master master-name="two-column-page-master">
<fo:region-body margin-top="3cm" region-name="body"
column-count="2"/>
<fo:region-before region-name="header" extent="2cm"/>
</fo:simple-page-master>
<fo:page-sequence-master master-name="one-column-page">
<fo:repeatable-page-master-reference
master-reference="one-column-page-master"/>
</fo:page-sequence-master>
<fo:page-sequence-master master-name="two-column-page">
<fo:repeatable-page-master-reference
master-reference="two-column-page-master"/>
</fo:page-sequence-master>
</fo:layout-master-set>
<xsl:apply-templates/>
</fo:root>
</xsl:template>
<xsl:template match="items">
<xsl:for-each-group select="item"
group-adjacent="@cols">
<xsl:choose>
<xsl:when test="@cols = 1">
<fo:page-sequence master-reference="one-column-page">
<fo:flow flow-name="body">
<xsl:for-each select="current-group()">
<xsl:apply-templates select="."/>
</xsl:for-each>
</fo:flow>
</fo:page-sequence>
</xsl:when>
<xsl:otherwise>
<fo:page-sequence master-reference="two-column-page">
<fo:flow flow-name="body">
<xsl:for-each select="current-group()">
<xsl:apply-templates select="."/>
</xsl:for-each>
</fo:flow>
</fo:page-sequence>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each-group>
</xsl:template>
<xsl:template match="item">
<fo:block margin-bottom="5cm">
<xsl:apply-templates/>
</fo:block>
</xsl:template>
</xsl:stylesheet>
Run Code Online (Sandbox Code Playgroud)
输出:
<?xml version="1.0" encoding="UTF-8"?>
<fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format">
<fo:layout-master-set>
<fo:simple-page-master master-name="one-column-page-master">
<fo:region-body margin-top="3cm" region-name="body" column-count="1"/>
</fo:simple-page-master>
<fo:simple-page-master master-name="two-column-page-master">
<fo:region-body margin-top="3cm" region-name="body" column-count="2"/>
<fo:region-before region-name="header" extent="2cm"/>
</fo:simple-page-master>
<fo:page-sequence-master master-name="one-column-page">
<fo:repeatable-page-master-reference master-reference="one-column-page-master"/>
</fo:page-sequence-master>
<fo:page-sequence-master master-name="two-column-page">
<fo:repeatable-page-master-reference master-reference="two-column-page-master"/>
</fo:page-sequence-master>
</fo:layout-master-set>
<fo:page-sequence master-reference="one-column-page">
<fo:flow flow-name="body">
<fo:block margin-bottom="5cm">Item 1</fo:block>
<fo:block margin-bottom="5cm">Item 2</fo:block>
<fo:block margin-bottom="5cm">Item 3</fo:block>
<fo:block margin-bottom="5cm">Item 4</fo:block>
<fo:block margin-bottom="5cm">Item 5</fo:block>
<fo:block margin-bottom="5cm">Item 6</fo:block>
<fo:block margin-bottom="5cm">Item 7</fo:block>
<fo:block margin-bottom="5cm">Item 8</fo:block>
<fo:block margin-bottom="5cm">Item 9</fo:block>
</fo:flow>
</fo:page-sequence>
<fo:page-sequence master-reference="two-column-page">
<fo:flow flow-name="body">
<fo:block margin-bottom="5cm">Item 10</fo:block>
</fo:flow>
</fo:page-sequence>
<fo:page-sequence master-reference="one-column-page">
<fo:flow flow-name="body">
<fo:block margin-bottom="5cm">Item 11</fo:block>
<fo:block margin-bottom="5cm">Item 12</fo:block>
<fo:block margin-bottom="5cm">Item 13</fo:block>
<fo:block margin-bottom="5cm">Item 14</fo:block>
<fo:block margin-bottom="5cm">Item 15</fo:block>
<fo:block margin-bottom="5cm">Item 16</fo:block>
<fo:block margin-bottom="5cm">Item 17</fo:block>
<fo:block margin-bottom="5cm">Item 18</fo:block>
</fo:flow>
</fo:page-sequence>
</fo:root>
Run Code Online (Sandbox Code Playgroud)