xsl muenchian 分组多个级别
Posted
技术标签:
【中文标题】xsl muenchian 分组多个级别【英文标题】:xsl muenchian grouping multiple levels 【发布时间】:2013-12-06 12:07:00 【问题描述】:我一直在尝试学习使用其他帖子来理解 muenchian 分组,但我正在努力将正确的分组转换为表格格式。分组需要分为两个级别,首先是赛季“年”,然后是每个赛季显示按“组”分组的匹配项。我已经设法将“组”分组,但它们都显示在最新一季,而不是分成各自的季节。这是xml的一个例子:
<DocumentElement>
<QueryResults>
<Years>2013/2014</Years>
<Group>1</Group>
<TeamNameShort>TeamA</TeamNameShort>
</QueryResults>
<QueryResults>
<Years>2013/2014</Years>
<Group>1</Group>
<TeamNameShort>TeamB</TeamNameShort>
</QueryResults>
<QueryResults>
<Years>2013/2014</Years>
<Group>2</Group>
<TeamNameShort>TeamC</TeamNameShort>
</QueryResults>
<QueryResults>
<Years>2013/2014</Years>
<Group>2</Group>
<TeamNameShort>TeamD</TeamNameShort>
</QueryResults>
<QueryResults>
<Years>2012/2013</Years>
<Group>1</Group>
<TeamNameShort>TeamA</TeamNameShort>
</QueryResults>
<QueryResults>
<Years>2012/2013</Years>
<Group>1</Group>
<TeamNameShort>TeamB</TeamNameShort>
</QueryResults>
<QueryResults>
<Years>2012/2013</Years>
<Group>2</Group>
<TeamNameShort>TeamC</TeamNameShort>
</QueryResults>
<QueryResults>
<Years>2012/2013</Years>
<Group>2</Group>
<TeamNameShort>TeamD</TeamNameShort>
</QueryResults>
</DocumentElement>
xsl 目前看起来像这样
<xsl:stylesheet
version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:cfg="http://tempuri.org/config"
exclude-result-prefixes="cfg"
>
<xsl:output method="html" indent="yes"/>
<!-- index by season -->
<xsl:key
name="Season"
match="QueryResults"
use="Years"
/>
<!-- index by "Pool" -->
<xsl:key
name="Pool"
match="QueryResults"
use="Group"
/>
<xsl:template match="DocumentElement">
<xsl:copy>
<!-- group by season -->
<xsl:apply-templates mode="season" select="
QueryResults[
generate-id()
=
generate-id(key('Season', Years)[1])
]
">
<xsl:sort select="Years" order="descending" />
</xsl:apply-templates>
</xsl:copy>
</xsl:template>
<!-- Season -->
<xsl:template match="QueryResults" mode="season">
<xsl:variable name="y" select="Years" />
<table>
<tbody>
<tr>
<td colspan="3">Season <xsl:value-of select="$y"/></td>
</tr>
<tr>
<th>Pos</th>
<th>Group/Year</th>
<th>Team</th>
</tr>
<!-- group Season by Pool -->
<xsl:apply-templates mode="pool" select="
key('Season', $y)[
generate-id()
=
generate-id(key('Pool',Group)[1])
]
">
</xsl:apply-templates>
</tbody>
</table>
</xsl:template>
<!-- Pool -->
<xsl:template match="QueryResults" mode="pool">
<xsl:variable name="g" select="Group" />
<tr>
<td colspan="3">Pool <xsl:value-of select="Group"/></td>
</tr>
<xsl:for-each select="key('Pool',$g)">
<tr>
<td><xsl:value-of select="Group"/></td>
<td><xsl:value-of select="Years"/></td>
<td><xsl:value-of select="TeamNameShort"/></td>
</tr>
</xsl:for-each>
</xsl:template>
<xsl:template match="QueryResults">
<xsl:copy-of select="." />
</xsl:template>
</xsl:stylesheet>
【问题讨论】:
【参考方案1】:问题在于,您不应该仅按 Group 元素进行分组,而应按给定 Year 的 Group 进行分组。实际上,您需要使用连接键
<xsl:key name="Pool" match="QueryResults" use="concat(Years, '|', Group)"/>
那么,只要您引用键,就可以简单地使用此连接值。例如
<xsl:apply-templates mode="pool" select="
key('Season', $y)
[
generate-id() = generate-id(key('Pool',concat(Years, '|', Group))[1])
]"/>
请注意,这里的 |
字符实际上可以是任何字符,只要它没有出现在您要连接的两个值中的任何一个中即可。
试试这个 XSLT
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:cfg="http://tempuri.org/config" exclude-result-prefixes="cfg">
<xsl:output method="html" indent="yes"/><!-- index by season -->
<xsl:key name="Season" match="QueryResults" use="Years"/><!-- index by "Pool" -->
<xsl:key name="Pool" match="QueryResults" use="concat(Years, '|', Group)"/>
<xsl:template match="DocumentElement">
<xsl:copy><!-- group by season -->
<xsl:apply-templates mode="season" select="QueryResults[generate-id() = generate-id(key('Season', Years)[1])]">
<xsl:sort select="Years" order="descending"/>
</xsl:apply-templates>
</xsl:copy>
</xsl:template><!-- Season -->
<xsl:template match="QueryResults" mode="season">
<xsl:variable name="y" select="Years"/>
<table>
<tbody>
<tr>
<td colspan="3">Season
<xsl:value-of select="$y"/></td>
</tr>
<tr>
<th>Pos</th>
<th>Group/Year</th>
<th>Team</th>
</tr><!-- group Season by Pool -->
<xsl:apply-templates mode="pool" select="key('Season', $y)[generate-id() = generate-id(key('Pool',concat(Years, '|', Group))[1])]"/>
</tbody>
</table>
</xsl:template>
<!-- Pool -->
<xsl:template match="QueryResults" mode="pool">
<xsl:variable name="g" select="concat(Years, '|', Group)"/>
<tr>
<td colspan="3">Pool
<xsl:value-of select="Group"/></td>
</tr>
<xsl:for-each select="key('Pool',$g)">
<tr>
<td>
<xsl:value-of select="Group"/>
</td>
<td>
<xsl:value-of select="Years"/>
</td>
<td>
<xsl:value-of select="TeamNameShort"/>
</td>
</tr>
</xsl:for-each>
</xsl:template>
<xsl:template match="QueryResults">
<xsl:copy-of select="."/>
</xsl:template>
</xsl:stylesheet>
【讨论】:
这很有意义,很好的解决方案 - 谢谢! 这是一个优雅的解决方案,写得很好。干得好!以上是关于xsl muenchian 分组多个级别的主要内容,如果未能解决你的问题,请参考以下文章
使用 XSLT 对 HTML 输出进行分组(muenchian 分组?)