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

XSLT 1.0多值截取问题:拆分Location元素为独立PL元素

解决XSLT拆分Location内容为独立PL元素的问题

问题回顾

你需要把输入的:

<Location>Wing: ; Room: A; Bed: NAH; Group: 195;</Location>

拆分为:

<PL.1>Wing: ;</PL.1>
<PL.2>Room: A;</PL.2>
<PL.3>Bed: NAH;</PL.3>
<PL.4>Group: 195;</PL.4>

之前用substring-before/substring-after的方法没处理好分隔符和空格的问题,导致输出异常。下面分XSLT版本给出正确实现:


方法1:XSLT 2.0及以上(推荐,更简洁)

利用XSLT 2.0自带的tokenize()函数,直接按"; "(分号+空格)拆分字符串,然后循环生成对应元素:

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:template match="Location">
    <!-- 按"; "拆分文本,过滤空项 -->
    <xsl:for-each select="tokenize(., '; ')[normalize-space(.) != '']">
      <!-- 生成PL.n元素,n是当前循环的位置 -->
      <xsl:element name="PL.{position()}">
        <!-- 拼接回分号,确保格式和输入一致 -->
        <xsl:value-of select="concat(., ';')"/>
      </xsl:element>
    </xsl:for-each>
  </xsl:template>
</xsl:stylesheet>

逻辑说明

  • tokenize(., '; '):把Location的文本按"; "分割成多个片段,比如第一个片段是Wing:,第二个是Room: A,以此类推。
  • [normalize-space(.) != '']:过滤掉拆分后可能出现的空字符串(比如原文本末尾的分号可能导致的空项)。
  • concat(., ';'):给每个拆分后的片段补回分号,保证输出内容和预期一致。
  • PL.{position()}:动态生成元素名称,position()会返回当前循环的序号(1、2、3、4)。

方法2:XSLT 1.0(兼容旧版本)

XSLT 1.0没有tokenize(),需要用递归模板来实现字符串拆分:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <!-- 匹配Location元素,启动递归拆分 -->
  <xsl:template match="Location">
    <xsl:call-template name="split-location">
      <xsl:with-param name="text" select="."/>
      <xsl:with-param name="index" select="1"/>
    </xsl:call-template>
  </xsl:template>

  <!-- 递归拆分模板 -->
  <xsl:template name="split-location">
    <xsl:param name="text"/>
    <xsl:param name="index"/>

    <!-- 找到第一个"; "的位置 -->
    <xsl:variable name="delimiter" select="'; '"/>
    <xsl:variable name="pos" select="string-length(substring-before($text, $delimiter)) + 1"/>

    <xsl:if test="normalize-space($text) != ''">
      <!-- 处理当前片段:如果有分隔符,取前面的部分;否则取全部文本 -->
      <xsl:variable name="current-part">
        <xsl:choose>
          <xsl:when test="contains($text, $delimiter)">
            <xsl:value-of select="substring-before($text, $delimiter)"/>
          </xsl:when>
          <xsl:otherwise>
            <!-- 处理最后一个片段,去掉末尾多余的分号(如果有的话) -->
            <xsl:value-of select="substring($text, 1, string-length($text)-1)"/>
          </xsl:otherwise>
        </xsl:choose>
      </xsl:variable>

      <!-- 生成PL元素 -->
      <xsl:element name="PL.{$index}">
        <xsl:value-of select="concat($current-part, ';')"/>
      </xsl:element>

      <!-- 递归处理剩余文本 -->
      <xsl:if test="contains($text, $delimiter)">
        <xsl:call-template name="split-location">
          <xsl:with-param name="text" select="substring-after($text, $delimiter)"/>
          <xsl:with-param name="index" select="$index + 1"/>
        </xsl:call-template>
      </xsl:if>
    </xsl:if>
  </xsl:template>
</xsl:stylesheet>

逻辑说明

  • 递归模板split-location每次处理一段文本,找到第一个"; "的位置,截取前面的内容作为当前PL元素的内容。
  • 处理最后一段时,因为原文本末尾有分号,所以需要去掉最后一个字符(分号)再补回来,保证格式正确。
  • 每次递归后index加1,生成对应的PL序号。

测试结果

两种方法都能输出你预期的XML结构,完美解决之前substring-before/substring-after处理不当导致的空元素和内容缺失问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 07:09:58