2013-08-28 15 views
2

我有以下問題,我認爲它有一個簡單的解決方案,我只是沒有這方面的知識。如何使用XSLT將連續號碼分組

我已經這個輸入例如:

<set> 
    <value>8</value> 
    <value>1</value> 
    <value>2</value> 
    <value>10</value> 
    <value>4</value> 
    <value>22</value> 
    <value>12</value> 
    <value>45</value> 
    <value>11</value> 
    <value>3</value> 
    <value>5</value> 
    <value>9</value> 
    <value>21</value> 
    <value>6</value> 
    <value>7</value> 
    <value>13</value> 
</set> 

我想創建與最大10個元素的每個其中數字是連續的並以升序的序列。

所需的輸出:

<MOrd> 
    <range> 
    <value>1</value> 
    <value>2</value> 
    <value>3</value> 
    <value>4</value> 
    <value>5</value> 
    <value>6</value> 
    <value>7</value> 
    <value>8</value> 
    <value>9</value> 
    <value>10</value> 
    </range> 
    <range> 
    <value>11</value> 
    <value>12</value> 
    <value>13</value> 
    </range> 
    <range> 
    <value>21</value> 
    <value>22</value> 
    </range> 
    <range> 
    <value>45</value> 
    </range> 
</Mord> 

我有這個代碼,到目前爲止,但不知道如何着手:

<MOrd> 
    <xsl:for-each select="$Set"> 
    <xsl:sort select="value" order="ascending" data-type="number"/> 
    <xsl:for-each-group select="value" group-by"value"> 
     <range> 
     <xsl:if test="."> 
      <value> 
      <xsl:value-of select="."/> 
      </value> 
     </xsl:if> 
     </range> 
    </xsl:for-each-group> 
    </xsl:for-each> 
</MOrd> 

你會如何走?

回答

3

我想你只需要組通過簡單的數學表達式的元素,以確定有多少次,每次10分爲數

<xsl:for-each-group select="value" group-by="floor((number(.) - 1) div 10)"> 

試試這個XSLT

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:template match="set"> 
    <MOrd> 
     <xsl:for-each-group select="value" group-by="floor((number(.) - 1) div 10)"> 
      <xsl:sort select="." order="ascending" data-type="number"/> 
      <range> 
       <xsl:for-each select="current-group()"> 
        <xsl:sort select="." order="ascending" data-type="number"/> 
        <xsl:copy-of select="." /> 
       </xsl:for-each> 
      </range> 
    </xsl:for-each-group> 
    </MOrd> 
    </xsl:template> 
</xsl:stylesheet> 

當適用於您的輸入XML,以下是輸出

<MOrd> 
    <range> 
     <value>1</value> 
     <value>2</value> 
     <value>3</value> 
     <value>4</value> 
     <value>5</value> 
     <value>6</value> 
     <value>7</value> 
     <value>8</value> 
     <value>9</value> 
     <value>10</value> 
    </range> 
    <range> 
     <value>11</value> 
     <value>12</value> 
     <value>13</value> 
    </range> 
    <range> 
     <value>21</value> 
     <value>22</value> 
    </range> 
    <range> 
     <value>45</value> 
    </range> 
</MOrd> 
+0

感謝您的快速回復,但那對我不起作用:請再次參見下面的問題 – user2726445

+0

更新的問題 – user2726445

+0

我對「number()」函數的回答做了小小的調整。你可以添加一個'。'如果你的處理器需要一個參數來表示當前節點。 –

1

我知道這是一個老問題,但我t似乎是手頭的問題,將連續的數字分組,沒有(完全)回答。你可以這樣做,在XSLT 2.0中使用group-starting-with如下(你排序輸入後):

<xsl:for-each-group select="value" 
    group-starting-with="value[xs:integer(preceding-sibling::value[1]) + 1 != xs:integer(.)]"> 
    <range> 
     <xsl:copy-of select="current-group()"/> 
    </range> 
</xsl:for-each-group> 

的方法有效,因爲它每次前一個兄弟是不是一個比當前節點下觸發一個新的組。如果您的輸入是1,2,3,6,7,8,12,16,17它將被分組爲1,2,3,6,7,8,1216,17

該解決方案適用於XSLT 2.0和3.0,但不適用於XSLT 1.0。