XSLT中带colspan的td宽度计算错误,请求解决方案
解决方案:处理带colspan的td宽度累加问题
我来帮你搞定这个问题!你的核心需求是当<td>带有colspan属性时,要累加对应合并列的宽度总和,而不是只取单个列的宽度。之前的代码存在两个关键问题:
- 拼写错误:把
colspan写成了colspam,导致无法正确读取属性值 - 起始列位置计算逻辑错误:仅考虑了前一个td的colspan,实际上需要累加所有前置td的colspan总和才能得到当前td对应的起始列位置
修改后的XSLT代码
<?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" exclude-result-prefixes="xs" version="2.0"> <xsl:output method="xml" indent="yes"/> <xsl:strip-space elements="*"/> <!-- 通用复制模板 --> <xsl:template match="@*|node()"> <xsl:copy> <xsl:apply-templates select="@*|node()"/> </xsl:copy> </xsl:template> <xsl:template match="td"> <xsl:copy> <xsl:attribute name="style"> <!-- 处理背景色 --> <xsl:if test="@fill"> <xsl:value-of select="concat('background-color: #', @fill, ';')"/> </xsl:if> <!-- 处理文本对齐 --> <xsl:if test="@align"> <xsl:value-of select="concat('text-align: ', @align, ';')"/> </xsl:if> <!-- 计算宽度 --> <xsl:variable name="start-col" select="sum(preceding-sibling::td/@colspan) + 1"/> <xsl:variable name="span-count" select="if (@colspan) then @colspan else 1"/> <!-- 获取对应列的宽度,去掉%转数值求和,再拼接% --> <xsl:variable name="total-width" select="sum(ancestor::table/colgroup/col[position() >= $start-col and position() < $start-col + $span-count]/substring(@width, 1, string-length(@width)-1))"/> <xsl:value-of select="concat('width: ', $total-width, '%;')"/> </xsl:attribute> <xsl:apply-templates/> </xsl:copy> </xsl:template> </xsl:stylesheet>
关键逻辑解释
计算起始列位置:
<xsl:variable name="start-col" select="sum(preceding-sibling::td/@colspan) + 1"/>累加当前td之前所有td的
colspan值,再加1得到当前td对应的第一个列的位置。比如你的示例中:- 第一个td的起始列是
0 + 1 = 1 - 第二个td的起始列是
5 + 1 = 6 - 第三个td的起始列是
5 + 1 + 1 = 7
- 第一个td的起始列是
处理合并列数量:
<xsl:variable name="span-count" select="if (@colspan) then @colspan else 1"/>如果td有
colspan就用它的值,否则默认取1(单个列)。宽度求和计算:
<xsl:variable name="total-width" select="sum(ancestor::table/colgroup/col[position() >= $start-col and position() < $start-col + $span-count]/substring(@width, 1, string-length(@width)-1))"/>先提取对应范围的
col元素,去掉width属性的%符号转成数值,对这些数值求和后,再拼接%得到最终的宽度值。
测试结果(针对你的输入XML)
处理后对应的td样式宽度会是:
- 第一个td:
19%+6%+4%+9%+8% = 46% - 第二个td:
3% - 第三个td:
16%+4%+15%+2%+14% = 51%
内容的提问来源于stack exchange,提问作者imran
相关产品推荐
相关产品推荐

