如何在fo:table-body的for-each中创建局部变量过滤fo:table-row
解决XSL-FO表格内局部变量过滤行的问题
核心误解纠正
你提到的“因缺少fo:block导致变量全局生效”是错误的——XSL中<xsl:variable>的作用域由它所在的XSL元素(比如<xsl:for-each>)决定,和FO元素(比如<fo:block>)完全无关。你当前代码里的$dist1、$dist2本来就是每个$trajectoryPoint循环内的局部变量,只会在当前循环迭代中生效,不存在全局覆盖的问题。
真正的问题所在
你的第二个<xsl:for-each>的节点选择表达式写错了:
otherNodeSet[/Distance >= $dist1 and /Distance < $dist2]
这里的/Distance是从根节点开始查找所有Distance节点,而不是otherNodeSet下的子节点。正确的写法应该是去掉开头的斜杠,或者用相对路径:
otherNodeSet[Distance >= $dist1 and Distance < $dist2]
或者更明确的:
otherNodeSet[./Distance >= $dist1 and ./Distance < $dist2]
修正后的完整代码
<fo:table-body> <xsl:for-each select="$trajectoryPoint"> <xsl:variable name="dist1" select="./distance1"/> <xsl:variable name="dist2" select="./distance2"/> <fo:table-row> <fo:table-cell> <fo:block> <xsl:text>REGULAR ROW INFO</xsl:text> </fo:block> </fo:table-cell> </fo:table-row> <xsl:for-each select="otherNodeSet[Distance >= $dist1 and Distance < $dist2]"> <fo:table-row> <fo:table-cell> <fo:block> <xsl:text>SPECIAL ROW INFO</xsl:text> </fo:block> </fo:table-cell> </fo:table-row> </xsl:for-each> </xsl:for-each> </fo:table-body>
可选优化:用模板分离逻辑
如果循环逻辑复杂,也可以把生成行的逻辑抽成模板,参数传递同样是局部生效的,和FO结构无关:
<fo:table-body> <xsl:for-each select="$trajectoryPoint"> <xsl:variable name="dist1" select="./distance1"/> <xsl:variable name="dist2" select="./distance2"/> <!-- 调用常规行模板 --> <xsl:call-template name="regular-row"/> <!-- 调用特殊行模板,传递参数 --> <xsl:for-each select="otherNodeSet[Distance >= $dist1 and Distance < $dist2]"> <xsl:call-template name="special-row"/> </xsl:for-each> </xsl:for-each> </fo:table-body> <!-- 定义常规行模板 --> <xsl:template name="regular-row"> <fo:table-row> <fo:table-cell> <fo:block> <xsl:text>REGULAR ROW INFO</xsl:text> </fo:block> </fo:table-cell> </fo:table-row> </xsl:template> <!-- 定义特殊行模板 --> <xsl:template name="special-row"> <fo:table-row> <fo:table-cell> <fo:block> <xsl:text>SPECIAL ROW INFO</xsl:text> </fo:block> </fo:table-cell> </fo:table-row> </xsl:template>
内容的提问来源于stack exchange,提问作者FKY_Baabaa
相关产品推荐
相关产品推荐

