按键和位置对 XSLT 进行分组和排序()
我试图显示按字母顺序排序的数据,以便以相同字母开头的项目位于不同的列中。在开始新列之前,这些列最多可容纳 10 个项目。我可以成功地将数据按字母顺序划分并按每列的项目数划分,但我很难将 2 结合起来:
按字母顺序划分:
<xsl:template match="/">
<xsl:key name="node-by-first-letter" match="node" use="substring(@email, 1, 1)" />
<div class="scroller-panel">
<xsl:for-each select="msxml:node-set($members)/node[count(. | key('node-by-first-letter', substring(@email, 1, 1))[1]) = 1]">
<xsl:sort select="@email" order="ascending"/>
<xsl:apply-templates select="." mode="group" />
</xsl:for-each></div></xsl:template>
<xsl:template match="node" mode="group">
<div class="column-312 scroller-item people-search-column fade-panel">
<h2>
<xsl:value-of select="Exslt.ExsltStrings:uppercase(substring(@email,1,1))"/>
</h2>
<ul class="stripe-list">
<xsl:apply-templates select="key('node-by-first-letter', substring(@email, 1, 1))" mode="item">
<xsl:sort select="@email" />
</xsl:apply-templates>
</ul>
</div>
</xsl:template>
<xsl:template match="node" mode="item">
<li>
<a href="4.0.1.person.profile.html">
<xsl:value-of select="@email"/>
</a>
</li>
</xsl:template>
除以每列的最大项目数:
<xsl:for-each select="msxml:node-set($members)/members/member[position() mod 10 = 1]">
<ul>
<xsl:for-each select=". | following-sibling::*[not(position() >= 10)]">
<li>
<xsl:value-of select="@email"/>
</li>
</xsl:for-each>
</ul>
</xsl:for-each>
首选输出如下:
http://rookery9.aviary.com.s3.amazonaws.com/9676500/9676792_3580_625x625.jpg
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我。 XSLT 2.0 解决方案:
当应用于此 XML 文档时(因为问题中没有提供此类内容!!!):
产生所需的输出 - 按首字母开头排序的名称并放入每列 10 项:
说明:
嵌套
xsl:for-each-group
-- 首先按起始字符分组,然后对于每个这样确定和排序的组 -- 按其项目应位于的列号。使用标准 XSLT 2.0 函数
current -grouping-key()
和current-group()
。II.XSLT 1.0 解决方案:
当应用于同一个 XML 文档时(如上所述),会产生相同的所需输出 - 名称按首字母和放入每列 10 项:
说明:
使用慕尼黑分组方法,加上排序,我们得到(按排序顺序)由所有以相同字符开头的名称组成的每组
name
元素.上面获得的每组
name
元素都通过将模板应用于其第一个name
元素来处理。整个组、其长度以及组中name
元素的索引(默认 = 1)作为参数传递。与
name
元素匹配的模板保证仅应用于列中的起始元素。它创建一个新的column
元素,并在其中复制该列的所有name
元素(从索引$pInd
开始,到索引结束) $pInd+$pColLength -1
不要求这些元素应该是同级元素(它们不是),如果每个name
不仅需要复制,还需要进行其他处理。这可以通过替换来完成
指令:-
I. XSLT 2.0 Solution:
when applied on this XML document (as no such was provided in the question!!!):
produces the desired output -- names sorted by starting first letter and put into columns of 10 items each:
Explanation:
Nested
xsl:for-each-group
-- first grouped by the starting character, then for each such determined and sorted group -- by the number of the column in which its items should be.Use of the standard XSLT 2.0 functions
current-grouping-key()
andcurrent-group()
.II.XSLT 1.0 Solution:
when applied on the same XML document (as above), the same desired output is produced -- names sorted by starting first letter and put into columns of 10 items each:
Explanation:
Using the Muenchian grouping method, plus sorting, we obtain (in sorted order) each group of
name
elements consisting of all names starting with the same character.Every group of
name
elements as obtained above is processed by applying templates to its firstname
element. The whole group, its length and the index of thename
element in the group (default = 1) are passed as parameters.The template matching a
name
element is guaranteed to be applied only on a starting element within a column. It creates a newcolumn
element and copies in it allname
elements for this column (starting from index$pInd
and ending at index$pInd+$pColLength -1
. There is no requirement that these elements should be siblings (and they aren't). If not just copying but also additional processing is required for eachname
, this can be done here by replacing the<xsl:copy-of>
instruction with:-