You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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() &lt; $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>

关键逻辑解释

  1. 计算起始列位置:

    <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
  2. 处理合并列数量:

    <xsl:variable name="span-count" select="if (@colspan) then @colspan else 1"/>
    

    如果td有colspan就用它的值,否则默认取1(单个列)。

  3. 宽度求和计算:

    <xsl:variable name="total-width" select="sum(ancestor::table/colgroup/col[position() >= $start-col and position() &lt; $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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 07:03:14