2

我有一个用等号(=)分隔的长字符串作为分隔符,如下所示:

AAA=BBBBB=CCCCCCCCCCCCCCCC=D=FFFFF=GG=H

子字符串可以有任意长度。如果我想获得第一个子字符串,我可以使用 substring-before 函数,如下所示:

<xsl:value-of select="substring-before($vari, '=')"/> 

但是有没有办法只获得第二个(第三个等)子字符串?我需要BBBBB而不是 AAA=BBBBB 和CCCCCCCCCCCCCCCC而不是 AAA=BBBBB =CCCCCCCCCCCCCCCC 所以 substring-before-last 不起作用。

4

3 回答 3

2

仅供参考,如果您有EXSLT 的字符串扩展元素可用,您可以执行以下操作:

<xsl:value-of select="str:tokenize($vari, '=')[2]" />

使用上面的字符串,这将返回BBBBB.

在 XPath 2.0 中,这个函数是内置的:

<xsl:value-of select="tokenize($vari, '=')[2]" />
于 2013-06-05T20:37:34.550 回答
0

使用 xslt-1.0:这可以通过 substring-after 和 substring-before 的组合来完成。
尝试:

<xsl:value-of select="substring-before(
                substring-after ($vari, , '=')
               , '=')"/>                    

对于 BBBBB
或:

<xsl:value-of select="substring-before(
                 substring-after ( substring-after ($vari,  '='),  '=')
                 , '=')"/>                  

对于CCCCCCCCCCCCCCCC。

注意:未经测试。

使用 xslt-2.0 可能会有更好的方法。

于 2013-06-05T14:39:50.687 回答
0

这是一个 xslt-1.0 解决方案,它不需要使用扩展,并且可以使用任意分隔符长度和分隔符出现:

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

  <xsl:template match="/">
    <xsl:call-template name="substring-nth-occurrence-position">
      <xsl:with-param name="string">aaa_#bbb_#ccc_#dddd_#ee</xsl:with-param>
      <xsl:with-param name="substr">_#</xsl:with-param>
      <xsl:with-param name="occurrence">3</xsl:with-param>
    </xsl:call-template>      
  </xsl:template>      

  <xsl:template name="substring-nth-occurrence-position">
    <xsl:param name="string"/>
    <xsl:param name="substr"/>
    <xsl:param name="occurrence"/>
    <xsl:param name="current_iteration" select="1"/> 
    <xsl:param name="accumulated_length" select="0"/> 

    <xsl:choose>
      <!-- in case occurrence is greater than the number of instances of substr return 0 -->
      <xsl:when test="not(contains($string, $substr))">0</xsl:when>

      <xsl:otherwise>
        <!-- determine the position of the next instance of substr in the (remaining part of ) string and add it to accumulated_length-->
        <xsl:variable name="v.accumulated_length_new">
          <xsl:variable name="v.idx.of.substr">
            <xsl:call-template name="instr">
              <xsl:with-param name="string" select="$string"/>
              <xsl:with-param name="substr" select="$substr"/>     
            </xsl:call-template>              
          </xsl:variable>    

          <xsl:value-of select="$accumulated_length + $v.idx.of.substr"></xsl:value-of>
        </xsl:variable> 

        <!-- if current_iteration equals occurrence then return accumulated length... -->
        <xsl:choose>
          <xsl:when test="$current_iteration= $occurrence ">
            <xsl:value-of select="$v.accumulated_length_new" />
          </xsl:when>  

          <!-- ... else run another iteration-->            
          <xsl:otherwise>
            <xsl:call-template name="substring-nth-occurrence-position">
              <xsl:with-param name="string" select="substring-after($string, $substr)"/>
              <xsl:with-param name="substr" select="$substr"/>
              <xsl:with-param name="occurrence" select="$occurrence"/>                 
              <xsl:with-param name="current_iteration" select="$current_iteration + 1"/> 
              <xsl:with-param name="accumulated_length" select="$v.accumulated_length_new + string-length($substr) - 1"/>                 
            </xsl:call-template>    
          </xsl:otherwise>
        </xsl:choose>  
      </xsl:otherwise>
    </xsl:choose>
  </xsl:template>    


  <!-- returns the position of the first occurrence of a substring in a string -->
  <xsl:template name="instr">
    <xsl:param name="string"/>
    <xsl:param name="substr"/>
    <xsl:value-of select="contains($string,$substr)*(1 + string-length(substring-before($string,$substr)))"  />
  </xsl:template>  

</xsl:stylesheet>

(上例的执行结果为14)。

于 2017-12-09T15:39:32.153 回答