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

XSLT2.0+FOP2.8中position()失效及指定节点值拼接问题咨询

问题与解决方案:XML节点位置提取与XSLT修正

需求说明

  • 提取XML中所有ItemValue的内容
  • 第3、4个Item对应的ItemValue需要拼接为一个条目,其余ItemValue保持原样单独生成条目

示例XML

<node>
  <Item>
    <ItemName><![CDATA[Name]]></ItemName>
    <ItemValue><![CDATA[Value]]></ItemValue>
  </Item>
  <Item>
    <ItemName><![CDATA[Name]]></ItemName>
    <ItemValue><![CDATA[Value]]></ItemValue>
  </Item>
  <Item>
    <ItemName><![CDATA[Name]]></ItemName>
    <ItemValue><![CDATA[Value3]]></ItemValue>
  </Item>
  <Item>
    <ItemName><![CDATA[Name]]></ItemName>
    <ItemValue><![CDATA[Value4]]></ItemValue>
  </Item>
  <Item>
   <ItemName><![CDATA[Name]]></ItemName>
   <ItemValue><![CDATA[Value]]></ItemValue>
  </Item>
</node>

现有XSLT代码的问题

原代码存在三处关键错误,导致Value3和Value4无法正常显示:

  1. 语法错误:<xsl:when>必须包裹在<xsl:choose>中,不能直接放在<xsl:if>内部
  2. 跳过逻辑失效:针对第4个Item的处理没有真正跳过,循环仍会处理该节点,导致空行或错误
  3. 路径引用错误:拼接时使用node/Item[position()+1]/ItemValue,这里的position()上下文混乱,无法正确获取下一个Item的内容

修正后的XSLT代码

<xsl:for-each select="node/Item">
  <xsl:variable name="currentPos" select="position()"/>
  <xsl:variable name="cellValue">
    <xsl:choose>
      <!-- 跳过第4个Item,因为已在第3个Item中拼接 -->
      <xsl:when test="$currentPos = 4">
      </xsl:when>
      <xsl:when test="$currentPos = 3">
        <xsl:value-of select="concat(ItemValue, ../Item[$currentPos + 1]/ItemValue)"/>
      </xsl:when>
      <xsl:otherwise>
        <xsl:value-of select="ItemValue"/>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:variable>

  <xsl:if test="$cellValue != ''">
    <fo:table-row>
      <fo:table-cell>
        <fo:block>
          <xsl:value-of select="$cellValue"/>
        </fo:block>
      </fo:table-cell>
    </fo:table-row>
  </xsl:if>
</xsl:for-each>

代码修正说明

  • 新增currentPos变量存储当前节点的位置,避免上下文混淆
  • 用<xsl:choose>替代原错误的<xsl:if>+<xsl:when>结构,保证语法合规
  • 第4个Item直接输出空值,配合后续的<xsl:if>过滤掉空行
  • 拼接时使用../Item[$currentPos + 1]/ItemValue,通过父节点定位下一个Item,确保路径正确

position()函数的正确使用场景

position()的返回值完全依赖当前的上下文环境,常见使用场景包括:

  • 在<xsl:for-each>循环中:返回当前节点在循环节点序列中的位置(从1开始计数)
  • 在<xsl:apply-templates>的匹配模板中:返回当前节点在被处理节点序列中的位置
  • 在节点集谓词中:比如node/Item[position() = 3],返回节点在当前筛选出的节点集中的位置
  • 注意:嵌套循环或不同节点集的谓词中,position()的上下文会切换,必须通过变量存储当前位置避免混淆

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 20:24:53