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

XSLT 1.0中能否匹配跨多XML节点的模板?含IF块转换需求

可行,这是可以实现的解决方案

XSLT 1.0完全能处理这类嵌套代码块的转换,核心思路是递归匹配IFBEGIN节点,找到对应的IFEND节点,将中间的LINE节点嵌套到<IF>元素内,同时避免重复处理节点。

示例原XML

<CODE>
  <LINE>
    <OPERATOR>ASSIGN</OPERATOR>
    <VALUE>x=1</VALUE>
  </LINE>
  <LINE>
    <OPERATOR>IFBEGIN</OPERATOR>
    <CONDITION>x>0</CONDITION>
  </LINE>
  <LINE>
    <OPERATOR>PRINT</OPERATOR>
    <VALUE>"Positive"</VALUE>
  </LINE>
  <LINE>
    <OPERATOR>IFEND</OPERATOR>
  </LINE>
  <LINE>
    <OPERATOR>END</OPERATOR>
  </LINE>
</CODE>

实现的XSLT 1.0代码

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output indent="yes"/>

  <!-- 匹配根节点,启动处理 -->
  <xsl:template match="/CODE">
    <CODE>
      <xsl:apply-templates select="LINE[1]" mode="process"/>
    </CODE>
  </xsl:template>

  <!-- 处理普通LINE节点(非IFBEGIN/IFEND) -->
  <xsl:template match="LINE" mode="process">
    <xsl:element name="{OPERATOR}">
      <xsl:copy-of select="*[not(local-name()='OPERATOR')]"/>
    </xsl:element>
    <!-- 处理下一个节点 -->
    <xsl:apply-templates select="following-sibling::LINE[1]" mode="process"/>
  </xsl:template>

  <!-- 处理IFBEGIN节点,构建IF块 -->
  <xsl:template match="LINE[OPERATOR='IFBEGIN']" mode="process">
    <IF>
      <xsl:copy-of select="CONDITION"/>
      <!-- 递归处理IFBEGIN到对应IFEND之间的所有节点 -->
      <xsl:apply-templates select="following-sibling::LINE[1]" mode="inside-if">
        <xsl:with-param name="end-pos" select="count(following-sibling::LINE[OPERATOR='IFEND'][1]/preceding-sibling::LINE) + 1"/>
      </xsl:apply-templates>
    </IF>
    <!-- 跳过IFEND及之前的节点,处理后续内容 -->
    <xsl:apply-templates select="following-sibling::LINE[OPERATOR='IFEND'][1]/following-sibling::LINE[1]" mode="process"/>
  </xsl:template>

  <!-- 处理IF块内部的节点,直到遇到对应IFEND -->
  <xsl:template match="LINE" mode="inside-if">
    <xsl:param name="end-pos"/>
    <xsl:if test="count(preceding-sibling::LINE) + 1 &lt; $end-pos">
      <xsl:element name="{OPERATOR}">
        <xsl:copy-of select="*[not(local-name()='OPERATOR')]"/>
      </xsl:element>
      <xsl:apply-templates select="following-sibling::LINE[1]" mode="inside-if">
        <xsl:with-param name="end-pos" select="$end-pos"/>
      </xsl:apply-templates>
    </xsl:if>
  </xsl:template>

  <!-- 忽略IFEND节点,避免重复处理 -->
  <xsl:template match="LINE[OPERATOR='IFEND']" mode="process"/>
</xsl:stylesheet>

转换后的结果

<CODE>
  <ASSIGN>
    <VALUE>x=1</VALUE>
  </ASSIGN>
  <IF>
    <CONDITION>x>0</CONDITION>
    <PRINT>
      <VALUE>"Positive"</VALUE>
    </PRINT>
  </IF>
  <END/>
</CODE>

关键逻辑说明

  1. 使用带mode的模板区分普通节点处理和IF块内部处理,避免节点重复匹配。
  2. 处理IFBEGIN时,先定位到对应的IFEND节点位置,递归处理中间所有LINE节点并嵌套到<IF>元素内。
  3. 处理完IF块后,直接跳转到IFEND的下一个节点继续处理,跳过IFBEGIN到IFEND之间的节点,防止重复转换。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 10:51:09