如何在XSLT中对<p>内所有image节点的width属性值求和?
解决XSLT中多张图片宽度求和的问题
哈哈,这个坑我之前踩过!你遇到的错误是因为substring-before()函数只能处理单个字符串值,但你直接传给它的是一个属性节点序列(也就是多个<image>的width属性值),它不知道该怎么处理多个输入,所以就抛出了"A sequence of more than one item is not allowed..."的错误。
下面给你两种可行的解决方案,根据你的XSLT版本选择:
方案1:XSLT 2.0+ 简洁写法(推荐)
如果你的XSLT处理器支持2.0或更高版本(比如Saxon),可以用XPath的for表达式遍历每个<image>节点,单独处理宽度后再求和:
<xsl:template match="p"> <xsl:value-of select="sum(for $img in image return number(substring-before($img/@width, 'cm')))"/> </xsl:template>
这里的for $img in image会逐个取出<p>下的每个<image>节点,然后对每个节点的width属性执行substring-before提取数字部分,转成数值后用sum()累加。
方案2:XSLT 1.0 兼容写法
如果你的环境只能用XSLT 1.0(比如老版本的Xalan),可以通过递归模板来累加宽度:
<xsl:template match="p"> <xsl:variable name="totalWidth"> <xsl:choose> <!-- 检查是否有图片节点 --> <xsl:when test="image"> <xsl:call-template name="sumImageWidths"> <xsl:with-param name="images" select="image"/> <xsl:with-param name="currentSum" select="0"/> </xsl:call-template> </xsl:when> <xsl:otherwise>0</xsl:otherwise> </xsl:choose> </xsl:variable> <!-- 输出总宽度 --> <xsl:value-of select="$totalWidth"/> </xsl:template> <!-- 递归求和的模板 --> <xsl:template name="sumImageWidths"> <xsl:param name="images"/> <xsl:param name="currentSum"/> <xsl:choose> <!-- 如果还有未处理的图片 --> <xsl:when test="$images"> <xsl:call-template name="sumImageWidths"> <!-- 传递剩下的图片(去掉第一个) --> <xsl:with-param name="images" select="$images[position() > 1]"/> <!-- 累加当前图片的宽度到总和 --> <xsl:with-param name="currentSum" select="$currentSum + number(substring-before($images[1]/@width, 'cm'))"/> </xsl:call-template> </xsl:when> <!-- 所有图片处理完,返回总宽度 --> <xsl:otherwise> <xsl:value-of select="$currentSum"/> </xsl:otherwise> </xsl:choose> </xsl:template>
这个方法通过递归遍历每个<image>节点,每次提取第一个图片的宽度加到总和里,直到所有图片处理完毕。
内容的提问来源于stack exchange,提问作者Hobbes
相关产品推荐
相关产品推荐

