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

如何用XSLT为XML表格rowspan对应的行添加<testentry/>元素?

修正XML表格rowspan对应位置插入的XSLT代码

需求回顾

当XML表格中的<td>元素带有rowspan属性时,需要在该单元格跨越的后续每一行的对应列位置插入<testentry/>空元素。原代码错误地在所有行插入元素,需修正逻辑实现精准插入。

示例输入XML

<table>
  <tr>
    <td rowspan="3">跨3行的单元格</td>
    <td>普通单元格1</td>
  </tr>
  <tr>
    <td>普通单元格2</td>
  </tr>
  <tr>
    <td>普通单元格3</td>
  </tr>
  <tr>
    <td>普通单元格4</td>
    <td rowspan="2">跨2行的单元格</td>
  </tr>
  <tr>
    <td>普通单元格5</td>
  </tr>
</table>

预期输出XML

<table>
  <tr>
    <td rowspan="3">跨3行的单元格</td>
    <td>普通单元格1</td>
  </tr>
  <tr>
    <testentry/>
    <td>普通单元格2</td>
  </tr>
  <tr>
    <testentry/>
    <td>普通单元格3</td>
  </tr>
  <tr>
    <td>普通单元格4</td>
    <td rowspan="2">跨2行的单元格</td>
  </tr>
  <tr>
    <td>普通单元格5</td>
    <testentry/>
  </tr>
</table>

修正后的XSLT代码(XSLT 1.0兼容)

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="xml" indent="yes"/>

  <!-- 处理表格,启动第一行的处理,初始无待处理rowspan -->
  <xsl:template match="table">
    <table>
      <xsl:if test="tr[1]">
        <xsl:apply-templates select="tr[1]">
          <xsl:with-param name="pending-rowspans" select="''"/>
        </xsl:apply-templates>
      </xsl:if>
    </table>
  </xsl:template>

  <!-- 处理单行,接收当前待处理的rowspan列表 -->
  <xsl:template match="tr">
    <xsl:param name="pending-rowspans"/>
    <tr>
      <!-- 1. 处理待处理rowspan:插入testentry并更新计数 -->
      <xsl:variable name="updated-pending">
        <xsl:for-each select="$pending-rowspans/span">
          <testentry/>
          <!-- 剩余次数>1时,保留到下一行的待处理列表 -->
          <xsl:if test=". > 1">
            <span><xsl:value-of select=". - 1"/></span>
          </xsl:if>
        </xsl:for-each>
      </xsl:variable>

      <!-- 2. 输出当前行的所有td元素 -->
      <xsl:apply-templates select="td"/>
    </tr>

    <!-- 准备下一行的待处理rowspan:更新后的旧记录 + 当前行新的rowspan(值>1的) -->
    <xsl:variable name="new-pending">
      <!-- 保留更新后仍需继续的rowspan -->
      <xsl:copy-of select="$updated-pending/span"/>
      <!-- 添加当前行中rowspan>1的td,计数为rowspan值-1 -->
      <xsl:for-each select="td[@rowspan and number(@rowspan) > 1]">
        <span><xsl:value-of select="number(@rowspan) - 1"/></span>
      </xsl:for-each>
    </xsl:variable>

    <!-- 递归处理下一行 -->
    <xsl:if test="following-sibling::tr[1]">
      <xsl:apply-templates select="following-sibling::tr[1]">
        <xsl:with-param name="pending-rowspans" select="$new-pending"/>
      </xsl:apply-templates>
    </xsl:if>
  </xsl:template>

  <!-- 复制td元素及其属性、内容 -->
  <xsl:template match="td">
    <xsl:copy>
      <xsl:copy-of select="@*"/>
      <xsl:copy-of select="node()"/>
    </xsl:copy>
  </xsl:template>
</xsl:stylesheet>

代码逻辑说明

  1. 跟踪待处理rowspan:通过pending-rowspans参数维护一个列表,记录每个列还需要插入<testentry/>的次数。
  2. 逐行处理:
    • 先遍历待处理列表,对应列插入<testentry/>,并将计数减1,计数为0的不再保留。
    • 输出当前行的所有<td>元素。
  3. 更新待处理列表:收集当前行中rowspan>1的<td>,将其rowspan值减1后加入下一行的待处理列表。
  4. 递归处理后续行:将更新后的待处理列表传递给下一行,重复上述流程。

这种方式能精准定位需要插入<testentry/>的列,避免无差别插入元素的问题。

内容的提问来源于stack exchange,提问作者ssr1012

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 13:22:13