>

토큰 화하고 정렬 한 다음 다시 결합해야하는 구분 된 문자열 (아래 예에서 공백으로 구분)이 있으며 XSLT 1.0을 사용하여이 모든 작업을 수행해야합니다. 어떻게해야합니까? xsl:sort 를 사용해야한다는 것을 알고 있습니다  어쨌든, 지금까지 시도한 모든 것은 나에게 일종의 오류를 주었다.

예를 들어,이 게시물 맨 아래에서 코드를 실행하면 다음과 같은 결과를 얻습니다.

strawberry blueberry orange raspberry lime lemon

대신 이걸 얻으려면 어떻게해야합니까? :

blueberry lemon lime orange raspberry strawberry

XSLT 1.0을 사용하고 있습니다.

다음은 제니 테니스 온 의 코드를 기반으로하는 코드입니다.

<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="tokenize1.xsl"?>
<xsl:stylesheet version="1.0"
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
  <xsl:call-template name="tokenize">
    <xsl:with-param name="string" select="'strawberry blueberry orange raspberry lime lemon'" />
  </xsl:call-template>
</xsl:template>
<xsl:template name="tokenize">
  <xsl:param name="string" />
  <xsl:param name="delimiter" select="' '" />
  <xsl:choose>
    <xsl:when test="$delimiter and contains($string, $delimiter)">
      <token>
        <xsl:value-of select="substring-before($string, $delimiter)" />
      </token>
      <xsl:text> </xsl:text>
      <xsl:call-template name="tokenize">
        <xsl:with-param name="string" 
                        select="substring-after($string, $delimiter)" />
        <xsl:with-param name="delimiter" select="$delimiter" />
      </xsl:call-template>
    </xsl:when>
    <xsl:otherwise>
      <token><xsl:value-of select="$string" /></token>
      <xsl:text> </xsl:text>
    </xsl:otherwise>
  </xsl:choose>
</xsl:template>
</xsl:stylesheet>


  • 답변 # 1

    다음은 비효율적 인 순수한 버전 1 솔루션입니다.

    <!-- Sort the tokens -->
    <xsl:template name="sortTokens">
      <xsl:param name="tokens" select="''"/>      <!-- The list of tokens -->
      <xsl:param name="separator" select="' '"/>  <!-- What character separates the tokens? -->
      <xsl:param name="pivot" select="''"/>       <!-- A pivot word used to divide the list -->
      <xsl:param name="lessThan" select="''"/>    <!-- Accumulator for tokens less than the pivot (with leading separator) -->
      <xsl:param name="moreThan" select="''"/>    <!-- Accumulator for tokens more than the pivot (with leading separator) -->
      <xsl:param name="leadWith" select="''"/>    <!-- If set, output this before sorting -->
      <xsl:param name="trailWith" select="''"/>   <!-- If set, output this after sorting -->
      <!-- The first token -->
      <xsl:variable name="firstToken" select="substring-before(concat($tokens,$separator),$separator)"/>
      <!-- Is the first token more or less than the pivot? -->
      <xsl:variable name="pivotVsFirstToken">
        <xsl:call-template name="compareStrings">
          <xsl:with-param name="a" select="$pivot"/>
          <xsl:with-param name="b" select="$firstToken"/>
        </xsl:call-template>
      </xsl:variable>
      <xsl:choose>
        <!-- No input, no output -->
        <xsl:when test="$tokens = '' and $pivot = ''"></xsl:when>
        <!-- At the outset, the first token becomes the pivot -->
        <xsl:when test="$pivot = ''">
          <xsl:value-of select="$leadWith"/>
          <xsl:call-template name="sortTokens">
            <xsl:with-param name="separator" select="$separator"/>
            <xsl:with-param name="tokens" select="substring-after($tokens,$separator)"/>
            <xsl:with-param name="pivot" select="$firstToken"/>
          </xsl:call-template>
          <xsl:value-of select="$trailWith"/>
        </xsl:when>
        <!-- When all tokens are in a bucket, output the pivot between sorted buckets -->
        <xsl:when test="$tokens = ''">
          <xsl:call-template name="sortTokens">
            <xsl:with-param name="separator" select="$separator"/>
            <xsl:with-param name="tokens" select="substring-after($lessThan,$separator)"/>
            <xsl:with-param name="trailWith" select="$separator"/>
          </xsl:call-template>
          <xsl:value-of select="$pivot"/>
          <xsl:call-template name="sortTokens">
            <xsl:with-param name="separator" select="$separator"/>
            <xsl:with-param name="tokens" select="substring-after($moreThan,$separator)"/>
            <xsl:with-param name="leadWith" select="$separator"/>
          </xsl:call-template>
        </xsl:when>
        <!-- If the first token is less than the pivot, put it in the lessThan bucket -->
        <xsl:when test="number($pivotVsFirstToken) = 1">
          <xsl:call-template name="sortTokens">
            <xsl:with-param name="separator" select="$separator"/>
            <xsl:with-param name="tokens" select="substring-after($tokens,$separator)"/>
            <xsl:with-param name="pivot" select="$pivot"/>
            <xsl:with-param name="lessThan" select="concat($separator,$firstToken,$lessThan)"/>
            <xsl:with-param name="moreThan" select="$moreThan"/>
          </xsl:call-template>
        </xsl:when>
        <!-- If the first token is more than the pivot, put it in the moreThan bucket -->
        <xsl:otherwise>
          <xsl:call-template name="sortTokens">
            <xsl:with-param name="separator" select="$separator"/>
            <xsl:with-param name="tokens" select="substring-after($tokens,$separator)"/>
            <xsl:with-param name="pivot" select="$pivot"/>
            <xsl:with-param name="lessThan" select="$lessThan"/>
            <xsl:with-param name="moreThan" select="concat($separator,$firstToken,$moreThan)"/>
          </xsl:call-template>
        </xsl:otherwise>
      </xsl:choose>
    </xsl:template>
    <!-- Quote an apostrophe -->
    <xsl:variable name="apos" select="&quot;'&quot;"/>
    <!-- The comparison order of the characters -->
    <xsl:variable name="characterOrder" select="concat(' !&quot;#$%&amp;',$apos,'()*+,-./0123456789:;&lt;=&gt;?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~')"/>
    <!-- Return -1 if string a is less, 1 if string b is less, or 0 if they are equal -->
    <xsl:template name="compareStrings">
      <xsl:param name="a" select="''"/>
      <xsl:param name="b" select="''"/>
      <xsl:choose>
        <xsl:when test="$a = '' and $b = ''">0</xsl:when>
        <xsl:when test="$a = ''">-1</xsl:when>
        <xsl:when test="$b = ''">1</xsl:when>
        <xsl:when test="substring($a,1,1) = substring($b,1,1)">
          <xsl:call-template name="compareStrings">
            <xsl:with-param name="a" select="substring($a,2)"/>
            <xsl:with-param name="b" select="substring($b,2)"/>
          </xsl:call-template>
        </xsl:when>
        <xsl:when test="contains(substring-after($characterOrder,substring($a,1,1)),substring($b,1,1))">-1</xsl:when>
        <xsl:otherwise>1</xsl:otherwise>
      </xsl:choose>
    </xsl:template>
    
    

  • 답변 # 2

    프로세서가 EXSLT를 지원하는 경우 str : tokenize

    를 사용하는 것이 좋습니다.

    정렬을 위해 xsl : sort를 사용하지 않는 이유는 무엇입니까?

    <xsl:template match="/">
      <xsl:variable name="tokens">
        <xsl:call-template name="tokenize">
          <xsl:with-param name="string" select="'strawberry blueberry orange raspberry lime lemon'" />
        </xsl:call-template>
      </xsl:variable>
      <xsl:for-each select="$tokens">
        <xsl:sort select="text()" />
        <xsl:value-of select="." />
        <xsl:if test="not(last())">
          <xsl:text> </xsl:text>
        </xsl:if>
      </xsl:for-each>
    </xsl:template>
    
    

    반복에 exsl : node-set해야 할 수도 있습니다.

  • 이전 javascript - cloud function에서 cloud dataflow 파이프 라인 트리거링 - 기능 시간 초과
  • 다음 sql - SELECT에서 작동하지 않는 MySQL 저장 프로 시저 (기본 질문)