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

XSLT中如何用FOR循环遍历@cpu[N]属性并自动取值?

解决XSLT中批量遍历带数字后缀的CPU属性问题

我懂你这种痛点——手动写@cpu0到@cpu19简直是重复劳动,想靠循环自动化处理太合理了!你之前用@cpu[0]的写法其实踩了XPath的语法坑:XPath里的方括号是用来过滤节点的,不是属性名的一部分,所以这种写法根本匹配不到对应的属性,自然没输出。

咱们换个思路,动态构造属性名来遍历就解决问题了,下面分两种常见的XSLT版本给出方案:

方案一:XSLT 2.0+(推荐,语法更简洁)

XSLT 2.0及以上支持原生的for循环,直接生成索引数字,再拼接成属性名匹配即可:

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:template match="/root">
    <div class="cpu-list">
      <!-- 循环0到19,覆盖20个CPU属性 -->
      <xsl:for-each select="0 to 19">
        <xsl:variable name="index" select="."/>
        <!-- 动态构造属性名并匹配 -->
        <xsl:variable name="cpu-attribute" select="current()/@*[local-name() = concat('cpu', $index)]"/>
        
        <!-- 输出属性值,即使属性不存在也能优雅处理 -->
        <p>
          CPU<xsl:value-of select="$index"/>: 
          <xsl:value-of select="$cpu-attribute" default="未配置"/>
        </p>
      </xsl:for-each>
    </div>
  </xsl:template>
</xsl:stylesheet>

如果不确定CPU的数量,还可以自动抓取所有带cpu前缀的属性,提取数字后缀排序后遍历,完全不用硬编码数量:

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:template match="/root">
    <div class="cpu-list">
      <!-- 筛选所有以cpu开头的属性,按数字后缀排序 -->
      <xsl:for-each select="@*[starts-with(local-name(), 'cpu')]">
        <xsl:sort select="number(substring-after(local-name(), 'cpu'))" data-type="number"/>
        <p>
          CPU<xsl:value-of select="substring-after(local-name(), 'cpu')"/>: 
          <xsl:value-of select="."/>
        </p>
      </xsl:for-each>
    </div>
  </xsl:template>
</xsl:stylesheet>

方案二:XSLT 1.0(兼容旧环境)

XSLT 1.0没有原生的for循环,需要用递归模板来实现循环逻辑:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <!-- 主模板触发递归循环 -->
  <xsl:template match="/root">
    <div class="cpu-list">
      <xsl:call-template name="loop-cpu">
        <xsl:with-param name="current-index" select="0"/>
        <xsl:with-param name="max-index" select="19"/> <!-- 定义最大CPU索引 -->
      </xsl:call-template>
    </div>
  </xsl:template>

  <!-- 递归循环模板 -->
  <xsl:template name="loop-cpu">
    <xsl:param name="current-index"/>
    <xsl:param name="max-index"/>

    <!-- 当索引未超过最大值时继续循环 -->
    <xsl:if test="$current-index <= $max-index">
      <xsl:variable name="attr-name" select="concat('cpu', $current-index)"/>
      <p>
        CPU<xsl:value-of select="$current-index"/>: 
        <xsl:value-of select="@*[name() = $attr-name]" />
      </p>

      <!-- 递归调用,索引自增1 -->
      <xsl:call-template name="loop-cpu">
        <xsl:with-param name="current-index" select="$current-index + 1"/>
        <xsl:with-param name="max-index" select="$max-index"/>
      </xsl:call-template>
    </xsl:if>
  </xsl:template>
</xsl:stylesheet>

关键要点总结

  • 不要用@cpu[0]这种错误写法,XPath的方括号不能用来拼接属性名;
  • 用concat('cpu', $index)动态构造属性名,再通过@*[local-name() = 构造的属性名]匹配目标属性;
  • 如果不需要固定数量,优先选择自动筛选cpu前缀属性的方式,扩展性更强。

内容的提问来源于stack exchange,提问作者Jakub Oškera

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.19 09:25:16