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

如何使用XSLT 1.0将XML层级结构转换为HTML表格?

解决XSLT转换XML层级到HTML表格时Id列位置不固定的问题

你遇到的核心问题是:当前的for-each会根据节点的祖先数量生成对应数量的<td>,然后直接追加Id的<td>,导致Id列的位置随着节点层级变化而错位。要解决这个问题,我们需要固定Level列的数量(这里是4列),先填充当前节点及其祖先的Name到对应Level列,再补充空的<td>填满剩余Level列,最后固定输出Id列。

解决方案代码

<xsl:template match="/">
  <table>
    <tr>
      <th>Level 1</th>
      <th>Level 2</th>
      <th>Level 3</th>
      <th>Level 4</th>
      <th>Id</th>
    </tr>
    <!-- 处理所有narrower节点,如果需要包含TopTerm,改成"//TopTerm | //narrower" -->
    <xsl:apply-templates select="//narrower"/>
  </table>
</xsl:template>

<xsl:template match="narrower">
  <tr>
    <!-- 从顶层节点到当前节点输出Name,reverse保证顺序是Level1到当前层级 -->
    <xsl:for-each select="reverse(ancestor-or-self::*)">
      <td><xsl:value-of select="@Name"/></td>
    </xsl:for-each>
    
    <!-- 计算需要补充的空td数量:总层级数4减去当前节点的层级深度 -->
    <xsl:variable name="current-level" select="count(ancestor-or-self::*)"/>
    <xsl:for-each select="1 to (4 - $current-level)">
      <td></td>
    </xsl:for-each>
    
    <!-- 固定位置输出Id列 -->
    <td><xsl:value-of select="@Id"/></td>
  </tr>
</xsl:template>

代码解释

  1. 顺序修正:reverse(ancestor-or-self::*)会把节点的祖先+自身的顺序从「当前节点→顶层节点」反转成「顶层节点→当前节点」,这样输出的<td>正好对应Level1到当前层级的内容。
  2. 填充空列:通过count(ancestor-or-self::*)获取当前节点的层级深度,用总层级数(4)减去这个深度得到需要补充的空<td>数量,确保Level列始终是4个。
  3. 固定Id列:最后统一输出Id的<td>,不管节点层级如何,它都会固定在表格的最后一列。

扩展:包含TopTerm节点的行

如果你需要把TopTerm本身也生成一行,可以修改根模板的select,并添加一个通用模板匹配TopTerm和narrower:

<xsl:template match="/">
  <table>
    <tr>
      <th>Level 1</th>
      <th>Level 2</th>
      <th>Level 3</th>
      <th>Level 4</th>
      <th>Id</th>
    </tr>
    <xsl:apply-templates select="//TopTerm"/>
  </table>
</xsl:template>

<xsl:template match="TopTerm | narrower">
  <tr>
    <xsl:for-each select="reverse(ancestor-or-self::*)">
      <td><xsl:value-of select="@Name"/></td>
    </xsl:for-each>
    <xsl:variable name="current-level" select="count(ancestor-or-self::*)"/>
    <xsl:for-each select="1 to (4 - $current-level)">
      <td></td>
    </xsl:for-each>
    <td><xsl:value-of select="@Id"/></td>
  </tr>
  <!-- 递归处理子节点 -->
  <xsl:apply-templates select="narrower"/>
</xsl:template>

这样生成的表格会包含TopTerm的行,并且所有节点的Id列都固定在最后一列,完全符合你的需求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 09:58:35