Xml XSL:分为列的列表

Xml XSL:分为列的列表,xml,xslt,Xml,Xslt,请帮帮我。有一个节点列表 <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... </l

请帮帮我。有一个节点列表

<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>

1.
2.
3.
4.
5.
6.
7.
等等
需要将列表中的“n”(任意数)等分

如果节点数没有被平均分割,那么让最后一组节点包含分割的剩余部分

例如,如果输入列表包含33个元素,并且输出应有4个均匀分布元素的部分。在出口处获得3到9个元素的部分,以及33个元素之和中包含6个元素的部分

输入

  • 一,
  • 二,
  • ...
  • 三十三
输出

<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列。


<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() &lt; $max]" />
  </list>
</xsl:template>

此解决方案不要求要分组到列中的节点应为同级节点

<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>
<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>

应用于此XML文档时

<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>
<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.
3.
4.
5.
6.
7.
8.
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
产生所需结果

<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>
<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.
3.
4.
5.
6.
7.
8.
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33

这是对OP在其对公认答案的评论中提出的一个新问题的单独回答:


非常感谢,您的代码完全正常工作。没错!还有一个问题:如何先按字母顺序对整个列表排序,然后再将其划分为列@加里尼诺

这几乎和以前一样简单,还需要一个额外的步骤:

  • 对节点进行排序

  • 应用
    xxx:node-set()
    扩展函数(提示:
    exslt:node-set()
    由大多数浏览器实现)转换步骤1中创建的RTF(结果树片段)。将其添加到常规节点集

  • 将解决原始问题的转换应用于步骤2的结果。上面


  • 我不清楚你想要的产量。你能根据“n”的一些示例值发布它吗?请参阅我发布的解决方案——它更通用,不要求节点是兄弟节点。这不是应该的。您在组中分成4个元素的组,并且必须分成4个组,这些组均匀分布所有元素。@KalininNew:您真的想告诉我您无法动态计算
    $max
    ?这里有一个提示
    上限(count(/list/item)div 4)
    非常感谢,您的代码已经完全正常工作了。没错!还有一个问题:如何先将整个列表按字母顺序排序,然后再将其分为几列?@kalininew:作为一个新问题提问,我很乐意回答:)更严重的是,我现在必须准备开始工作——可能会在3小时内回答。谢谢,我将等待答复。