能否通过XSL:FO根据页面位置控制元素可见性?Apache FOP场景
用XSL-FO + Apache FOP实现段落水平线的条件显示
首先明确:标准XSL-FO的markers没法直接完成这个需求,因为markers的设计目的是将内容提取到页眉/页脚等重复区域,不能用来判断元素是否为当前页面主体的最后一个元素。但借助Apache FOP的扩展特性,可以实现这个效果。
可行方案(基于Apache FOP扩展)
Apache FOP提供了fox:retrieve-marker扩展,能读取当前页面内指定marker的内容,我们可以用它来追踪页面主体的最后一个元素,进而控制水平线的可见性:
1. 定义Marker追踪页面内最后一个主体元素
给每个需要加水平线的段落(或主体内容块)末尾加一个marker,用元素的唯一ID作为标记值。由于同一页面内的marker会被后续元素覆盖,最终页面内的last-body-element marker值就是最后一个主体元素的ID:
<fo:block> <xsl:apply-templates select="."/> <!-- 标记当前段落,后续段落会覆盖这个marker的值 --> <fo:marker marker-class-name="last-body-element"> <xsl:value-of select="generate-id(.)"/> </fo:marker> </fo:block>
2. 添加带条件判断的水平线
在段落之后插入水平线块,通过fox:retrieve-marker获取当前页面最后一个主体元素的ID,和当前段落的ID对比。如果匹配,说明这个水平线是页面主体的最后一个元素,直接隐藏:
<fo:block border-top="1pt solid black" margin-top="0.5em"> <xsl:if test="fox:retrieve-marker('last-body-element', 'page') = generate-id(.)"> <xsl:attribute name="visibility">hidden</xsl:attribute> </xsl:if> </fo:block>
3. 确保FOP扩展启用
默认情况下Apache FOP已经启用了扩展,如果你有自定义配置,确认fop.xconf中包含扩展配置:
<fop version="1.0"> <extensions> <extension id="http://xmlgraphics.apache.org/fop/extensions" implementation="org.apache.fop.fo.extensions.ExtensionElementMapping"/> </extensions> </fop>
无扩展的折中方案(仅适用于文档末尾场景)
如果不能用FOP扩展,只能做折中处理:给所有段落加水平线,除了文档的最后一个段落。同时给水平线设置keep-with-next="always",确保水平线和下一段落在同一页面。但这个方案无法处理“某页面内最后一个元素但不是文档最后”的情况。
内容的提问来源于stack exchange,提问作者Crypto Mike
相关产品推荐
相关产品推荐

