<list>
<item>1</item>
<item>2</item>
<item>3</item>
<item>4</item>
<item>5</item>
<item>6</item>
<item>7</item>
and so on...
</list>
需要划分“n”(任意数)等份的列表。
如果节点数没有平均分配,那么让最后一组节点包含除法的剩余部分。
例如,如果输入列表包含33个元素,并且输出应该包含4个具有均匀分布元素的部分。在出口处获得3个部分到9个元素,一个部分有6个元素,总数为33。
输入
<ul>
<li>1</li>
<li>2</li>
...
<li>33</li>
</ul>
输出
<ul>
<li>1</li>
<li>2</li>
...
<li>9</li>
</ul>
<ul>
<li>10</li>
<li>11</li>
...
<li>18</li>
</ul>
<ul>
<li>19</li>
<li>11</li>
...
<li>27</li>
</ul>
<ul>
<li>28</li>
<li>30</li>
...
<li>33</li>
</ul>
分为4个小组。
答案 0 :(得分:5)
此解决方案不要求将要分组到列中的节点作为兄弟:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:variable name="vNodes" select="/*/*/text()"/>
<xsl:param name="vNumParts" select="4"/>
<xsl:variable name="vNumCols" select=
"ceiling(count($vNodes) div $vNumParts)"/>
<xsl:template match="/">
<table border="1">
<xsl:for-each select=
"$vNodes[position() mod $vNumCols = 1]">
<xsl:variable name="vCurPos" select=
"(position()-1)*$vNumCols +1"/>
<tr>
<xsl:for-each select=
"$vNodes[position() >= $vCurPos
and
not(position() > $vCurPos + $vNumCols -1)
]">
<td><xsl:copy-of select="."/></td>
</xsl:for-each>
</tr>
</xsl:for-each>
</table>
</xsl:template>
</xsl:stylesheet>
应用于此XML文档:
<list>
<item>1</item>
<item>2</item>
<item>3</item>
<item>4</item>
<item>5</item>
<item>6</item>
<item>7</item>
<item>8</item>
<item>9</item>
<item>10</item>
<item>11</item>
<item>12</item>
<item>13</item>
<item>14</item>
<item>15</item>
<item>16</item>
<item>17</item>
<item>18</item>
<item>19</item>
<item>20</item>
<item>21</item>
<item>22</item>
<item>23</item>
<item>24</item>
<item>25</item>
<item>26</item>
<item>27</item>
<item>28</item>
<item>29</item>
<item>30</item>
<item>31</item>
<item>32</item>
<item>33</item>
</list>
生成了想要的结果:
<table border="1">
<tr>
<td>1</td>
<td>2</td>
<td>3</td>
<td>4</td>
<td>5</td>
<td>6</td>
<td>7</td>
<td>8</td>
<td>9</td>
</tr>
<tr>
<td>10</td>
<td>11</td>
<td>12</td>
<td>13</td>
<td>14</td>
<td>15</td>
<td>16</td>
<td>17</td>
<td>18</td>
</tr>
<tr>
<td>19</td>
<td>20</td>
<td>21</td>
<td>22</td>
<td>23</td>
<td>24</td>
<td>25</td>
<td>26</td>
<td>27</td>
</tr>
<tr>
<td>28</td>
<td>29</td>
<td>30</td>
<td>31</td>
<td>32</td>
<td>33</td>
</tr>
</table>
答案 1 :(得分:2)
这是对OP提出的一个新问题的单独答案,他对接受的答案的评论之一是:
非常感谢,您的代码完全正常运行。没错!然后是另一个问题:如何首先按字母顺序对整个列表进行排序,然后将其除以列? - @kalininew
这几乎和以前一样简单,需要额外增加一步:
对节点进行排序
应用xxx:node-set()
扩展功能(提示:exslt:node-set()
由大多数浏览器实现)将上面步骤1中创建的RTF(结果树片段)转换为常规节点集
将解决原始问题的转换应用于上述步骤2的结果。
答案 2 :(得分:1)
<xsl:variable name="max" select="4" />
<xsl:template match="/">
<xsl:apply-templates select="list" mode="split" />
</xsl:template>
<xsl:template match="list" mode="split">
<xsl:apply-templates select="item[position() mod $max = 1]" mode="split" />
</xsl:template>
<xsl:template match="item" mode="split">
<list>
<xsl:copy-of select=". | following-sibling::item[position() < $max]" />
</list>
</xsl:template>