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

如何基于tag=0属性实现表格行数据居中对齐?

XSLT 1.0 实现座位中心对齐表格的解决方案

核心逻辑

XSLT 1.0里的变量是只读不可修改的,而且作用域仅限定义它的上下文,没法像常规编程语言那样在遍历过程中更新变量来统计最大值。所以得先全局计算所有行中tag=0的<seat>元素的前置兄弟数量的最大值,再基于这个值给每行生成左对齐的占位单元格,实现中心对齐效果。

具体实现方案

方案一:用扩展函数(兼容性好,大部分处理器支持)

1. 定义键值对定位每行的tag=0座位

用<xsl:key>快速找到每行里的目标座位,方便后续统计前置兄弟数:

<xsl:key name="target-seat" match="seat[@tag='0']" use="generate-id(..)"/>

2. 计算全局最大前置兄弟数

先把所有行的前置兄弟数收集到变量里,再转成节点集排序取最大值:

<!-- 收集所有行的前置兄弟数量 -->
<xsl:variable name="all-left-counts">
  <xsl:for-each select="//row[seat[@tag='0']]">
    <count><xsl:value-of select="count(key('target-seat', generate-id(.))/preceding-sibling::seat)"/></count>
  </xsl:for-each>
</xsl:variable>

<!-- 转成节点集并排序取最大值 -->
<xsl:variable name="max-left">
  <xsl:for-each select="exsl:node-set($all-left-counts)/count">
    <xsl:sort select="." data-type="number" order="descending"/>
    <xsl:if test="position() = 1">
      <xsl:value-of select="."/>
    </xsl:if>
  </xsl:for-each>
</xsl:variable>

注:exsl:node-set()是多数XSLT处理器(比如Saxon、Xalan)都支持的扩展函数,用来把XSLT1.0里的结果树片段转成可遍历的节点集。

3. 生成对齐的表格行

对每一行,先算当前行tag=0座位的前置兄弟数,再补够和最大值的差值作为左占位单元格,然后输出所有座位:

<table border="1">
  <xsl:for-each select="//row">
    <tr>
      <!-- 生成左侧占位空单元格 -->
      <xsl:variable name="current-target" select="seat[@tag='0']"/>
      <xsl:variable name="current-left" select="count($current-target/preceding-sibling::seat)"/>
      <xsl:for-each select="1 to ($max-left - $current-left)">
        <td></td>
      </xsl:for-each>
      
      <!-- 输出该行所有座位 -->
      <xsl:for-each select="seat">
        <td><xsl:value-of select="@number"/></td>
      </xsl:for-each>
      
      <!-- 可选:补右侧空单元格让每行宽度一致 -->
      <xsl:variable name="current-right" select="count($current-target/following-sibling::seat)"/>
      <!-- 同理计算全局最大后置兄弟数,这里省略重复逻辑 -->
      <!-- <xsl:for-each select="1 to ($max-right - $current-right)">
        <td></td>
      </xsl:for-each> -->
    </tr>
  </xsl:for-each>
</table>

方案二:纯XSLT 1.0递归模板(无扩展,兼容性拉满)

如果不能用扩展函数,就写个递归模板遍历所有tag=0的座位,逐个比较找出最大值:

<!-- 递归模板找最大值 -->
<xsl:template name="get-max-left">
  <xsl:param name="seat-list"/>
  <xsl:param name="current-max" select="0"/>
  <xsl:choose>
    <xsl:when test="$seat-list">
      <xsl:variable name="current-count" select="count($seat-list[1]/preceding-sibling::seat)"/>
      <xsl:call-template name="get-max-left">
        <xsl:with-param name="seat-list" select="$seat-list[position() > 1]"/>
        <xsl:with-param name="current-max" select="if ($current-count > $current-max) then $current-count else $current-max"/>
      </xsl:call-template>
    </xsl:when>
    <xsl:otherwise>
      <xsl:value-of select="$current-max"/>
    </xsl:otherwise>
  </xsl:choose>
</xsl:template>

<!-- 调用模板获取最大值 -->
<xsl:variable name="max-left">
  <xsl:call-template name="get-max-left">
    <xsl:with-param name="seat-list" select="//seat[@tag='0']"/>
  </xsl:call-template>
</xsl:variable>

之后的表格生成逻辑和方案一完全一样,直接用这个$max-left变量就行。

关键注意点

  • XSLT 1.0的变量是一次性赋值的,不能中途修改,所以必须先全局算出最大值再用,这是解决你遇到的XPST0008作用域错误的核心
  • 如果不需要每行宽度完全一致,右侧的空单元格可以不用补,只处理左侧占位就能实现tag=0座位的中心对齐
  • 递归模板是纯标准XSLT语法,适合不能用扩展函数的场景

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.08 03:02:01