2013-10-18 55 views
4

我有一種情況,我需要檢查可能連續編號的屬性值,並在開始值和結束值之間輸入破折號。檢查連續編號的屬性

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

理想的產出將是...

8-11, 20 

我可以令牌化屬性爲獨立的價值,但我不能確定如何檢查是否在「valueXXXXX」末數爲接連前一個值。

我使用XSLT 2.0

回答

4

您可以使用xsl:for-each-group@group-adjacent測試爲number()值減去position()

這一招顯然是由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