我一直在研究使用<xsl:sort>
和变量对XML进行排序的线程,但仍无法让我的排序工作。这是上下文的一些XML结构:
<?xml version="1.0" encoding="UTF-8"?>
<tournament>
<match date="2015-12-18">
<team name="FIRST" score="1" />
<team name="SECOND" score="0" />
</match>
<match date="2015-12-20">
<team name="FIRST" score="1" />
<team name="THIRD" score="3" />
</match>
<match date="2015-12-23">
<team name="THIRD" score="5" />
<team name="SECOND" score="1" />
</match>
</tournament>
我希望显示球队和总分的列表(一场比赛赢得了两分,一场比赛输了零点,两队平等一分)我使用这段代码:
<xsl:variable name="matches" select="//match"/>
<table border="1" width="100%">
<tr>
<th>TEAMS</th>
<th>POINTS</th>
</tr>
<xsl:for-each select="distinct-values(tournament/match/team/@name)">
<xsl:variable name="this" select="."/>
<xsl:variable name="points" select="sum($matches/team[@name=$this and (@score>following-sibling::*/@score
or @score>preceding-sibling::*/@score)]/2) + sum($matches/team[@name=$this
and (@score=following-sibling::*/@score or @score=preceding-sibling::*/@score)]/1) "/>
<tr>
<td><xsl:value-of select="."/></td>
<td><xsl:value-of select="$points"/></td>
</tr>
</xsl:for-each>
</table>
这有助于我展示:
| TEAMS | POINTS |
|--------------------------|
| FIRST | 2 |
| SECOND | 1 |
| THIRD | 3 |
现在,我想通过点对此结果进行排序以显示:
| TEAMS | POINTS |
|--------------------------|
| THIRD | 3 |
| FIRST | 2 |
| SECOND | 1 |
那么,我如何通过变量<xsl:for-each>
$points
进行排序
答案 0 :(得分:2)
您无法按变量排序。为了避免两次计算得分,我会在两次通过中做到这一点:
XSLT 2.0
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" omit-xml-declaration="yes" version="1.0" encoding="utf-8" indent="yes"/>
<xsl:key name="wins" match="team[@score > ancestor::match/team/@score]" use="@name"/>
<xsl:key name="draws" match="team[not(@score!=ancestor::match/team/@score)]" use="@name"/>
<xsl:template match="/tournament">
<!-- first pass -->
<xsl:variable name="teams">
<xsl:for-each-group select="match/team" group-by="@name">
<team name="{@name}" points="{2 * count(key('wins', @name)) + count(key('draws', @name))}"/>
</xsl:for-each-group>
</xsl:variable>
<!-- output -->
<table border="1" width="100%">
<tr>
<th>TEAMS</th>
<th>POINTS</th>
</tr>
<xsl:for-each select="$teams/team">
<xsl:sort select="@points" data-type="number" order="descending"/>
<tr>
<td><xsl:value-of select="@name"/></td>
<td><xsl:value-of select="@points"/></td>
</tr>
</xsl:for-each>
</table>
</xsl:template>
</xsl:stylesheet>