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

如何限制XSLT输出中符合条件的<job>元素数量?

解决XSLT1.0中带条件过滤时限制输出<job>数量的问题

方法一:纯XSLT实现(推荐)

核心思路是先筛选出符合输出条件的节点,再遍历并限制数量,这样position()就能准确统计实际要输出的<job>数量:

  1. 定义变量设定最大输出数,比如$maxJobs
  2. 修改<xsl:for-each>的select表达式,直接过滤出满足PositionId和JobDescription都存在的Results节点
  3. 在遍历过程中用position() <= $maxJobs判断是否输出

修改后的完整代码:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" exclude-result-prefixes="xsl in lang user" xmlns:in="http://www.composite.net/ns/transformation/input/1.0" xmlns:lang="http://www.composite.net/ns/localization/1.0" xmlns:f="http://www.composite.net/ns/function/1.0" xmlns:msxsl="urn:schemas-microsoft-com:xslt" xmlns:user="urn:my-scripts">
  <msxsl:script language="C#" implements-prefix="user">
    <msxsl:assembly name="System.Web" />
    <msxsl:using namespace="System.Web" />
    <msxsl:using namespace="System.IO" />
    <msxsl:using namespace="System.Net" />
<![CDATA[

public string HTMLDecode(string JoDesc) {
 string jd = JoDesc;
 jd = HttpUtility.HtmlDecode(jd);
 return jd;
}
]]>
  </msxsl:script>
  <xsl:output method="xml" version="1.0" encoding="utf-8" />
  
  <!-- 设定最大输出的job数量 -->
  <xsl:variable name="maxJobs" select="5"/>

  <xsl:template match="/">
    <xsl:element name="jobs">
      <!-- 直接筛选符合条件的Results节点,避免后续if判断 -->
      <xsl:for-each select="//Results[.//PositionId and JobDescription]">
        <!-- 仅当位置小于等于设定值时输出 -->
        <xsl:if test="position() <= $maxJobs">
          <xsl:element name="job">
            <xsl:element name="client_job_id">
              <xsl:text disable-output-escaping="yes">&lt;![CDATA[</xsl:text>
              <xsl:value-of
                select=".//PositionId"
                disable-output-escaping="yes"
              />
              <xsl:text disable-output-escaping="yes">]]&gt;</xsl:text>
            </xsl:element>

            <xsl:element name="description">
              <xsl:text disable-output-escaping="yes">&lt;![CDATA[</xsl:text>
              <xsl:value-of
                select="user:HTMLDecode(JobDescription)"
                disable-output-escaping="yes"
              />
              <xsl:text disable-output-escaping="yes">]]&gt;</xsl:text>
            </xsl:element>
          </xsl:element>
        </xsl:if>
      </xsl:for-each>
    </xsl:element>
  </xsl:template>
</xsl:stylesheet>

方法二:通过C#脚本实现计数器

如果你需要保留原有代码结构,不想修改for-each的筛选逻辑,可以利用已有的msxsl脚本添加计数器:

  1. 在C#脚本中添加静态计数器变量和判断方法
  2. 在输出<job>前调用判断方法,只有计数器未达上限时才输出
  3. 在模板开始时重置计数器,避免多次转换时计数混乱

修改后的完整代码:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" exclude-result-prefixes="xsl in lang user" xmlns:in="http://www.composite.net/ns/transformation/input/1.0" xmlns:lang="http://www.composite.net/ns/localization/1.0" xmlns:f="http://www.composite.net/ns/function/1.0" xmlns:msxsl="urn:schemas-microsoft-com:xslt" xmlns:user="urn:my-scripts">
  <msxsl:script language="C#" implements-prefix="user">
    <msxsl:assembly name="System.Web" />
    <msxsl:using namespace="System.Web" />
    <msxsl:using namespace="System.IO" />
    <msxsl:using namespace="System.Net" />
<![CDATA[
private static int jobCounter = 0;
// 设定最大job数量
private static int maxJobCount = 5;

public string HTMLDecode(string JoDesc) {
 string jd = JoDesc;
 jd = HttpUtility.HtmlDecode(jd);
 return jd;
}

// 判断是否可以添加新job,同时递增计数器
public bool CanAddJob() {
    if (jobCounter < maxJobCount) {
        jobCounter++;
        return true;
    }
    return false;
}

// 重置计数器,避免多次转换时计数残留
public void ResetJobCounter() {
    jobCounter = 0;
}
]]>
  </msxsl:script>
  <xsl:output method="xml" version="1.0" encoding="utf-8" />

  <xsl:template match="/">
    <!-- 转换开始时重置计数器 -->
    <xsl:value-of select="user:ResetJobCounter()"/>
    <xsl:element name="jobs">
      <xsl:for-each select="//Results">
        <xsl:variable name="allElementsExist">
          <xsl:if test=".//PositionId and JobDescription">
            <xsl:value-of select="'true'" />
          </xsl:if>
        </xsl:variable>
        <!-- 同时判断元素存在性和计数器上限 -->
        <xsl:if test="$allElementsExist = 'true' and user:CanAddJob()">
          <xsl:element name="job">
            <xsl:element name="client_job_id">
              <xsl:text disable-output-escaping="yes">&lt;![CDATA[</xsl:text>
              <xsl:value-of
                select=".//PositionId"
                disable-output-escaping="yes"
              />
              <xsl:text disable-output-escaping="yes">]]&gt;</xsl:text>
            </xsl:element>

            <xsl:element name="description">
              <xsl:text disable-output-escaping="yes">&lt;![CDATA[</xsl:text>
              <xsl:value-of
                select="user:HTMLDecode(JobDescription)"
                disable-output-escaping="yes"
              />
              <xsl:text disable-output-escaping="yes">]]&gt;</xsl:text>
            </xsl:element>
          </xsl:element>
        </xsl:if>
      </xsl:for-each>
    </xsl:element>
  </xsl:template>
</xsl:stylesheet>

说明

  • 方法一纯XSLT实现更简洁,符合XSLT的声明式编程风格,推荐优先使用
  • 方法二适合需要保留原有循环逻辑的场景,利用C#脚本的可变变量实现计数(XSLT1.0原生变量不可变,因此需要扩展脚本)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 20:06:00