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

XSLT按自定义状态排序取最差值报错:xsl:sort不能在此处使用

解决XSLT中xsl:sort位置错误及获取最差状态值的问题

问题背景

你需要根据给定的状态优先级(从优到差:0, 1, 2, 3, 4, 5, 6, G, U, Q, ., V, R, I, X, D),从一组<Details>节点中找出最差的状态(对应编码值最大的项)。你尝试通过编码状态为数字后排序取最大值,但遇到了错误:

Code: 0x80004005 Keyword xsl:sort may not be used here

错误原因

XSLT语法有明确要求:xsl:sort必须是xsl:for-each或xsl:apply-templates的第一个直接子元素。你的代码中,xsl:for-each内部先定义了$Status变量,之后才放置xsl:sort,这违反了语法规则,导致报错。

解决方案

方案1:XSLT 1.0兼容版本

调整xsl:for-each的结构,将xsl:sort放在最前面,直接使用模板返回的编码值作为排序键,然后取排序后的第一个元素的编码:

<xsl:variable name="MaxWorstStatus">
  <xsl:for-each select="//ic:Details/ic:status">
    <!-- 把xsl:sort放在for-each的第一个子位置 -->
    <xsl:sort select="call-template('encodeStatus')" data-type="number" order="descending"/>
    <xsl:if test="position() = 1">
      <xsl:call-template name="encodeStatus">
        <xsl:with-param name="Node" select="."/>
      </xsl:call-template>
    </xsl:if>
  </xsl:for-each>
</xsl:variable>

<xsl:template name="encodeStatus">
  <xsl:param name="Node"/>
  <xsl:choose>
    <xsl:when test="$Node='0'">0</xsl:when>
    <xsl:when test="$Node='1'">1</xsl:when>
    <xsl:when test="$Node='2'">2</xsl:when>
    <xsl:when test="$Node='3'">3</xsl:when>
    <xsl:when test="$Node='4'">4</xsl:when>
    <xsl:when test="$Node='5'">5</xsl:when>
    <xsl:when test="$Node='6'">6</xsl:when>
    <xsl:when test="$Node='G'">7</xsl:when>
    <xsl:when test="$Node='U'">8</xsl:when> <!-- 修正编码对应优先级顺序:G比U更优 -->
    <xsl:when test="$Node='Q'">9</xsl:when>
    <xsl:when test="$Node='.'">10</xsl:when>
    <xsl:when test="$Node='V'">11</xsl:when>
    <xsl:when test="$Node='R'">12</xsl:when>
    <xsl:when test="$Node='I'">13</xsl:when>
    <xsl:when test="$Node='X'">14</xsl:when>
    <xsl:when test="$Node='D'">15</xsl:when>
    <xsl:otherwise>0</xsl:otherwise> <!-- 默认设为最优,避免异常值干扰 -->
  </xsl:choose>
</xsl:template>

注意:你之前的encodeStatus模板中把U编码为7,但根据优先级顺序G在U前面(更优),所以修正了编码对应关系,确保排序逻辑和预期一致。

方案2:XSLT 2.0+简化版本

如果使用XSLT 2.0或更高版本,可以利用序列和max()函数,代码更简洁高效:

<xsl:variable name="status-map" as="map(xs:string, xs:integer)">
  <xsl:map>
    <xsl:map-entry key="'0'" select="0"/>
    <xsl:map-entry key="'1'" select="1"/>
    <xsl:map-entry key="'2'" select="2"/>
    <xsl:map-entry key="'3'" select="3"/>
    <xsl:map-entry key="'4'" select="4"/>
    <xsl:map-entry key="'5'" select="5"/>
    <xsl:map-entry key="'6'" select="6"/>
    <xsl:map-entry key="'G'" select="7"/>
    <xsl:map-entry key="'U'" select="8"/>
    <xsl:map-entry key="'Q'" select="9"/>
    <xsl:map-entry key="'.'" select="10"/>
    <xsl:map-entry key="'V'" select="11"/>
    <xsl:map-entry key="'R'" select="12"/>
    <xsl:map-entry key="'I'" select="13"/>
    <xsl:map-entry key="'X'" select="14"/>
    <xsl:map-entry key="'D'" select="15"/>
  </xsl:map>
</xsl:variable>

<xsl:variable name="MaxWorstStatus" select="max(//ic:Details/ic:status/($status-map(.)))"/>

这个版本直接通过映射表将状态转换为数字,然后用max()函数一步获取最大值,无需排序,逻辑更清晰。

验证结果

修正后的代码会正确处理你的测试数据(状态值:U,0,X,D,1,2),返回对应D的编码15,完全符合预期。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.13 09:15:34