XSLT中计算XML游泳程序长度:含祖先repetitionCount的乘法求和
计算带重复次数的游泳程序总长度(XSLT解决方案)
XSLT 2.0+ 简洁实现
利用XSLT 2.0及以上版本的product()函数,可以直接对每个<lengthAsDistance>节点计算其与所有祖先<repetitionCount>的乘积之和:
<xsl:value-of select="sum(descendant::lengthAsDistance/(number(.) * product(ancestor::repetition/repetitionCount/number(.))))"/>
说明
descendant::lengthAsDistance:选中所有目标长度节点product(ancestor::repetition/repetitionCount/number(.)):计算当前长度节点所有祖先<repetition>下的<repetitionCount>数值的乘积(无重复节点时返回1,不影响原数值)- 每个长度值乘以对应乘积后,用
sum()求和得到总长度
XSLT 1.0 兼容实现
XSLT 1.0无内置乘积函数,需通过递归模板实现:
步骤1:实现乘积计算模板
<xsl:template name="calc-product"> <xsl:param name="nodes" select="/.." /> <xsl:param name="result" select="1" /> <xsl:choose> <xsl:when test="$nodes"> <xsl:call-template name="calc-product"> <xsl:with-param name="nodes" select="$nodes[position() > 1]" /> <xsl:with-param name="result" select="$result * number($nodes[1])" /> </xsl:call-template> </xsl:when> <xsl:otherwise> <xsl:value-of select="$result" /> </xsl:otherwise> </xsl:choose> </xsl:template>
步骤2:实现加权求和模板
<xsl:template name="sum-weighted-length"> <xsl:param name="length-nodes" select="/.." /> <xsl:param name="total" select="0" /> <xsl:choose> <xsl:when test="$length-nodes"> <xsl:variable name="current-val" select="number($length-nodes[1])" /> <xsl:variable name="multiplier"> <xsl:call-template name="calc-product"> <xsl:with-param name="nodes" select="$length-nodes[1]/ancestor::repetition/repetitionCount" /> </xsl:call-template> </xsl:variable> <xsl:call-template name="sum-weighted-length"> <xsl:with-param name="length-nodes" select="$length-nodes[position() > 1]" /> <xsl:with-param name="total" select="$total + $current-val * $multiplier" /> </xsl:call-template> </xsl:when> <xsl:otherwise> <xsl:value-of select="$total" /> </xsl:otherwise> </xsl:choose> </xsl:template>
步骤3:在<program>上下文调用求和模板
<xsl:call-template name="sum-weighted-length"> <xsl:with-param name="length-nodes" select="descendant::lengthAsDistance" /> </xsl:call-template>
两种方案最终计算结果均为4459,符合预期需求。
内容的提问来源于stack exchange,提问作者bartneck
相关产品推荐
相关产品推荐

