XSL choose分支语句语法问题求助:条件判断始终匹配otherwise分支
嘿,我一眼就瞅到问题所在啦!你遇到的核心问题是上下文节点搞错了——你的<xsl:choose>里测试的@accountno和@cycle根本不是当前遍历的meterread节点的属性,自然匹配不到任何<xsl:when>分支,只能走到<xsl:otherwise>里。
咱们来拆解一下你的代码结构:
你用<xsl:for-each select="lineitems/servicelocation/group[@chargetype='METERED']/meter/meterread[...]">循环的是meterread元素,这意味着当前上下文(也就是你直接用@xxx访问的节点)是meterread,而@accountno、@cycle这些属性应该是在更高层级的节点上(比如group或者servicelocation),不是meterread自己的属性。
解决方案:指定正确的节点路径
你需要调整测试条件里的属性路径,指向包含@accountno和@cycle的上层节点。根据你的XML结构路径,meterread的父节点是meter,再往上是group,所以如果@accountno在group节点上,你可以用相对路径../../@accountno来访问它;如果@cycle在其他层级,同理调整路径。
修改后的<xsl:choose>代码示例:
<xsl:choose> <xsl:when test="../../@accountno='264835'"> <fo:table-cell padding="2pt"><fo:block text-align="center"><xsl:value-of select="format-number(@previousread * .1, '###,###,##0.000')"/></fo:block></fo:table-cell> <fo:table-cell padding="2pt"><fo:block text-align="center"><xsl:value-of select="format-number(@current * .1, '###,###,##0.000')"/></fo:block></fo:table-cell> </xsl:when> <xsl:when test="../../@accountno='201631'"> <fo:table-cell padding="2pt"><fo:block text-align="center"><xsl:value-of select="format-number(@previousread * .1, '###,###,##0.000')"/></fo:block></fo:table-cell> <fo:table-cell padding="2pt"><fo:block text-align="center"><xsl:value-of select="format-number(@current * .1, '###,###,##0.000')"/></fo:block></fo:table-cell> </xsl:when> <xsl:when test="../../@accountno='130159'"> <fo:table-cell padding="2pt"><fo:block text-align="center"><xsl:value-of select="format-number(@previousread * .1, '###,###,##0.000')"/></fo:block></fo:table-cell> <fo:table-cell padding="2pt"><fo:block text-align="center"><xsl:value-of select="format-number(@current * .1, '###,###,##0.000')"/></fo:block></fo:table-cell> </xsl:when> <xsl:when test="../../@cycle='5'"> <!-- 同样调整cycle的路径,如果cycle在group节点的话 --> <fo:table-cell padding="2pt"><fo:block text-align="center"><xsl:value-of select="format-number(@previousread * .1, '###,###,##0.000')"/></fo:block></fo:table-cell> <fo:table-cell padding="2pt"><fo:block text-align="center"><xsl:value-of select="format-number(@current * .1, '###,###,##0.000')"/></fo:block></fo:table-cell> </xsl:when> <xsl:otherwise> <fo:table-cell padding="2pt"><fo:block text-align="center"><xsl:value-of select="format-number(@previousread * .748, '###,###,##0.000')"/></fo:block></fo:table-cell> <fo:table-cell padding="2pt"><fo:block text-align="center"><xsl:value-of select="format-number(@current * .748, '###,###,##0.000')"/></fo:block></fo:table-cell> </xsl:otherwise> </xsl:choose>
更清晰的写法:用变量存储上层节点
如果你担心相对路径容易搞混,也可以在<xsl:for-each>开头先定义变量,把上层节点存起来,之后直接用变量访问属性:
<xsl:for-each select="lineitems/servicelocation/group[@chargetype='METERED']/meter/meterread[string-length(@previousdate) > 0]"> <!-- 存储包含accountno的group节点 --> <xsl:variable name="targetGroup" select="../.." /> <xsl:sort select="concat(substring(@previousdate, 7, 4),substring(@previousdate, 1, 2),substring(@previousdate, 4, 2))" data-type="number"/> <fo:table-row font-size="8pt"> <fo:table-cell padding="2pt"> <fo:block><xsl:value-of select="../@number"/></fo:block> </fo:table-cell> <xsl:choose> <xsl:when test="$targetGroup/@accountno='264835'"> <!-- 后续代码不变 --> </xsl:when> <!-- 其他when分支同理用$targetGroup/@accountno --> <xsl:when test="$targetGroup/@cycle='5'"> <!-- ... --> </xsl:when> <xsl:otherwise> <!-- ... --> </xsl:otherwise> </xsl:choose> <!-- 后续代码不变 --> </fo:table-row> </xsl:for-each>
这样调整后,你的<xsl:when>条件就能正确匹配到目标属性,不会再默认走到<xsl:otherwise>分支啦!
内容的提问来源于stack exchange,提问作者Damon Combs

