我有以下问题,我认为它有一个简单的解决方案,我只是没有这方面的知识。
我输入了这个例子:
<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>
你怎么会离开这里?
答案 0 :(得分: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>
答案 1 :(得分:1)
我知道这是一个老问题,但似乎手头的问题,将连续数字分组,并没有(完全)回答。您可以使用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
,12
和16,17
。
该解决方案适用于XSLT 2.0和3.0,但不适用于XSLT 1.0。