XSL中Boolean变量display在when块内更新后未生效问题求助
问题根源:XSL变量是不可变的
你遇到的核心问题是XSL中的变量一旦定义就无法修改值,它和编程语言里的可变变量逻辑完全不同:
- 外层模板里定义的
$display初始值为false(),作用域覆盖整个show模板。 - 你在
<xsl:when>块里重新定义的$display是一个局部变量,仅在该<fo:block>内部生效,出了这个块就失效了。 - 后续
<fo:block>中访问的始终是外层最初定义的$display,所以值一直是false()。
解决方案
根据你的需求(仅显示一次Logo),推荐两种简洁的实现方式:
方法一:提前判断,一次性显示Logo
直接先检查是否存在符合条件的水果,确认后只显示一次Logo,再循环处理所有水果:
<xsl:template name="show"> <fo:block> Fruits </fo:block> <!-- 仅当存在符合条件的Fruit时,显示一次Logo --> <xsl:if test="Fruits/Fruit[contains(type, 'Ground')]"> <fo:block> <xsl:variable name="FilePath" select="/imagesDir"/> <xsl:variable name="FullFileName" select="concat($FilePath,'\', $Fruits_Logo_ImageFile)"/> <fo:external-graphic src="url(file:///{$FullFileName})" content-height="scale-to-fit" height="15pt" content-width="15pt"/> Fruits </fo:block> </xsl:if> <!-- 循环处理所有水果项 --> <xsl:for-each select="Fruits/Fruit"> <fo:block> <xsl:value-of select="name"/> </fo:block> </xsl:for-each> </xsl:template>
方法二:用模板递归传递状态(适合复杂逻辑)
如果需要在循环过程中动态跟踪状态,可以通过模板递归+参数传递的方式模拟"可变"状态:
<xsl:template name="show"> <fo:block> Fruits </fo:block> <!-- 初始调用时,display状态为false --> <xsl:call-template name="process-fruits"> <xsl:with-param name="display" select="false()"/> <xsl:with-param name="fruit-list" select="Fruits/Fruit"/> </xsl:call-template> </xsl:template> <xsl:template name="process-fruits"> <xsl:param name="display"/> <xsl:param name="fruit-list"/> <!-- 递归终止条件:水果列表为空 --> <xsl:if test="$fruit-list"> <xsl:variable name="current-fruit" select="$fruit-list[1]"/> <xsl:choose> <xsl:when test="not($display) and contains($current-fruit/type, 'Ground')"> <fo:block> <xsl:variable name="FilePath" select="/imagesDir"/> <xsl:variable name="FullFileName" select="concat($FilePath,'\', $Fruits_Logo_ImageFile)"/> <fo:external-graphic src="url(file:///{$FullFileName})" content-height="scale-to-fit" height="15pt" content-width="15pt"/> Fruits </fo:block> <!-- 传递更新后的状态给下一次递归 --> <xsl:call-template name="process-fruits"> <xsl:with-param name="display" select="true()"/> <xsl:with-param name="fruit-list" select="$fruit-list[position() > 1]"/> </xsl:call-template> </xsl:when> <xsl:otherwise> <fo:block> <xsl:value-of select="$current-fruit/name"/> </fo:block> <!-- 传递原有状态给下一次递归 --> <xsl:call-template name="process-fruits"> <xsl:with-param name="display" select="$display"/> <xsl:with-param name="fruit-list" select="$fruit-list[position() > 1]"/> </xsl:call-template> </xsl:otherwise> </xsl:choose> </xsl:if> </xsl:template>
内容的提问来源于stack exchange,提问作者developer new
相关产品推荐
相关产品推荐

