2013-10-18 4 views
4

연속적으로 번호가 매겨진 속성 값을 확인하고 시작과 끝 값 사이에 대시를 입력해야하는 경우가 있습니다.연속 번호가 매겨진 속성을 확인하십시오.

<root> 
<ref id="value00008 value00009 value00010 value00011 value00020"/> 
</root> 

이상적인 출력이 될 것 ...

8-11, 20 

내가 별도의 값으로 속성을 토큰 화 수 있지만, 나는 "valueXXXXX"의 끝 부분에있는 번호가 있는지 확인하는 방법을 확실 해요 이전 값에 연속.

난 당신이 position()을 뺀 number()@group-adjacent 테스트를 xsl:for-each-group을 사용할 수 있습니다 XSLT 2.0

답변

4

을 사용하고 있습니다.

이 트릭은 분명히 David Carlisle에 의해 발명되었다, according to Michael Kay.

<?xml version="1.0" encoding="UTF-8"?> 
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    version="2.0"> 
    <xsl:output indent="yes"/> 
    <xsl:template match="/"> 
     <xsl:variable name="vals" 
       select="tokenize(root/ref/@id, '\s?value0*')[normalize-space()]"/> 

     <xsl:variable name="condensed-values" as="item()*"> 

      <xsl:for-each-group select="$vals" 
           group-adjacent="number(.) - position()"> 
       <xsl:choose> 
        <xsl:when test="count(current-group()) > 1"> 
        <!--a sequence of successive numbers, 
         grab the first and last one and join with '-' --> 
        <xsl:sequence select=" 
           string-join(current-group()[position()=1 
               or position()=last()] 
              ,'-')"/> 
        </xsl:when> 
        <xsl:otherwise> 
         <!--single value group--> 
         <xsl:sequence select="current-group()"/> 
        </xsl:otherwise> 
       </xsl:choose> 
      </xsl:for-each-group> 
     </xsl:variable> 

     <xsl:value-of select="string-join($condensed-values, ',')"/> 

    </xsl:template> 
</xsl:stylesheet> 
+0

이것은 좋은 대답이다. 한 가지가 없어졌습니다. 그룹이 마지막 항목이고 ","을 출력하지 않으면 어떻게 테스트 할 수 있습니까? – Jeff

+0

끝에 쉼표가 없어야합니다. 당신이 그것을 실행 했습니까? string-join()은 두 번째 문자열 매개 변수의 값을 사용하여 첫 번째 매개 변수의 시퀀스에서 값을 연결하고 마지막 항목에 추가하지 않습니다. –

+0

나는 본다. 출력해야 할 부분을 수정해야했습니다. 별도의 태그에 래핑 된 각 항목이 필요하므로 내 실행에서 문자열 조인을 제거했습니다. – Jeff

관련 문제