使用 XSL-FO 在下一个兄弟为空时隐藏块
Posted
技术标签:
【中文标题】使用 XSL-FO 在下一个兄弟为空时隐藏块【英文标题】:Hiding block when the next sibiling is empty with XSL-FO 【发布时间】:2021-11-05 21:59:27 【问题描述】:我正在使用 Apache FOP 生成报告,我的模板是这样的:
<xsl:template match="LOGO">
<xsl:param name="imgLogo">
<xsl:value-of select="IMG" />
</xsl:param>
<fo:external-graphic content-
src="$imgLogo" />
</xsl:template>
<xsl:template match="MYREPORT">
<fo:block>
<xsl:apply-templates select="LOGO" />
</fo:block>
<fo:block>
<xsl:value-of select="PAG_1" />
</fo:block>
<fo:block page-break-before="always">
<xsl:apply-templates select="LOGO" />
</fo:block>
<fo:block>
<xsl:value-of select="PAG_2" />
</fo:block>
<fo:block page-break-before="always">
<xsl:apply-templates select="LOGO" />
</fo:block>
<fo:block>
<xsl:value-of select="PAG_3" />
</fo:block>
</xsl:template>
如果下一个兄弟块 (PAGE) 为空,我必须隐藏“LOGO”块(在每个 PAGE 之前)。
例如,使用以下输入:
<MYREPORT>
<LOGO>
<IMG>data:image/png;base64,[cutted]</IMG>
</LOGO>
<PAG_1>Page 1</PAG_1>
<PAG_2>Page 2</PAG_2>
</MYREPORT>
应该打印出来:
LOGO
Page 1
(new page)
LOGO
Page 2
它正在打印以下内容:
LOGO
Page 1
(new page)
LOGO
Page 2
(new page)
LOGO
有什么想法吗?谢谢
【问题讨论】:
仅供参考。本题纯属XSL,与XSL FO无关。 仅供参考。本题纯属XSL,与XSL FO无关。 【参考方案1】:最直接的方法是在PAG_3
的代码周围加上xsl:if
:
<xsl:template match="MYREPORT">
<fo:block>
<xsl:apply-templates select="LOGO" />
</fo:block>
<fo:block>
<xsl:value-of select="PAG_1" />
</fo:block>
<fo:block page-break-before="always">
<xsl:apply-templates select="LOGO" />
</fo:block>
<fo:block>
<xsl:value-of select="PAG_2" />
</fo:block>
<xsl:if test="PAG_3">
<fo:block page-break-before="always">
<xsl:apply-templates select="LOGO" />
</fo:block>
<fo:block>
<xsl:value-of select="PAG_3" />
</fo:block>
</xsl:if>
</xsl:template>
另一种方法(我会使用)是使用xsl:apply-templates
选择 PAG_* 元素,以便仅为存在的元素生成结果:
<xsl:template match="MYREPORT">
<xsl:apply-templates select="PAG_1 | PAG_2 | PAG_3" />
</xsl:template>
<xsl:template match="PAG_1 | PAG_2 | PAG_3">
<fo:block>
<xsl:if test="position() != 1">
<xsl:attribute name="page-break-before">always</xsl:attribute>
</xsl:if>
<xsl:apply-templates select="../LOGO" />
</fo:block>
<fo:block>
<xsl:apply-templates />
</fo:block>
</xsl:template>
【讨论】:
这对我来说是一种魔法,但这正是我想要的……谢谢! 使用xsl:apply-templates
可以更容易地使用源文档的结构来确定结果。它通常比尝试预测每个可能的源文档的结构(如您所发现的)更简单。任何对 XSLT 的良好介绍都会向您展示如何使用 xsl:apply-templates
和多个模板规则,而不是试图在一个模板中完成所有事情。 (我还将第二个示例中的xsl:value-of
更改为xsl:apply-templates
:如果PAG_1
等都有任何内联元素,xsl:value-of
只会为您提供它们的字符串值。)以上是关于使用 XSL-FO 在下一个兄弟为空时隐藏块的主要内容,如果未能解决你的问题,请参考以下文章