使用count和sum对变量XSLT进行排序

时间:2013-10-30 10:54:30

标签: xml xslt

我正在尝试使用sum和count与变量对每个地方进行“平均目标得分”排序:

我的XML是:

<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="rugby.xsl"?>

<rugby>
    <games>
        <game>
            <place>USA</place>
            <team1>Team1</team1>
            <team1>Team2</team1>
            <score>20-1</score>
        </game>
        <game>
            <place>USA</place>
            <team1>Team1</team1>
            <team1>Team2</team1>
            <score>2-20</score>
        </game>
        <game>
            <place>USA</place>
            <team1>Team1</team1>
            <team1>Team2</team1>
            <score>24-11</score>
        </game>
        <game>
            <place>USA</place>
            <team1>Team1</team1>
            <team1>Team2</team1>
            <score>12-41</score>
        </game>
        <game>
            <place>USA</place>
            <team1>Team1</team1>
            <team1>Team2</team1>
            <score>20-100</score>
        </game>
        <game>
            <place>Mexico</place>
            <team1>Team1</team1>
            <team1>Team2</team1>
            <score>1-32</score>
        </game>
        <game>
            <place>Mexico</place>
            <team1>Team1</team1>
            <team1>Team2</team1>
            <score>2-100</score>
        </game>
        <game>
            <place>Peru</place>
            <team1>Team1</team1>
            <team1>Team2</team1>
            <score>2-10</score>
        </game>
        <game>
            <place>Peru</place>
            <team1>Team1</team1>
            <team1>Team2</team1>
            <score>100-2</score>
        </game>
    </games>
</rugby>

和XSLT:

<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">

    <xsl:template match="/rugby">
        <html>
            <head>
                <link rel="stylesheet" href="my_style.css" type="text/css"/>
            </head>
            <body>
                <table>
                    <tr>
                        <td>Place</td>
                        <td>Average Goals Score</td>
                        <td>Average Goals Conceded</td>
                    </tr>
                    <xsl:variable name="numOfGames" select="count(//games/game)"/>
                    <xsl:for-each select="//games/game/place">
                        <xsl:variable name="nameOfPlace" select="text()"/>
                        <xsl:variable name="score" select="sum(//games/game/place[contains(., $nameOfPlace)]/following-sibling::score/number(substring-before(.,'-')))"/>
                        <xsl:variable name="conceded" select="sum(//games/game/place[contains(., $nameOfPlace)]/following-sibling::score/number(substring-after(.,'-')))"/>

                        <tr>
                            <td><xsl:value-of select="place"/></td>
                            <td><xsl:value-of select="$score div $numOfGames"/></td>
                            <td><xsl:value-of select="$conceded div $numOfGames"/></td>
                        </tr>
                    </xsl:for-each>
                </table>
            </body>
        </html>
    </xsl:template>
</xsl:stylesheet>

我想在变量后进行排序:

<xsl:sort select="$score div $numOfGames" order="ascending" data-type="number"/>

但它不起作用,因为排序必须在每个下面(我必须先创建变量)。我试图删除变量sum和count但是我不能删除变量nameOfPlace,所以排序根本不起作用。

<xsl:for-each select="//games/game/place">
                        <xsl:variable name="nameOfPlace" select=""/>
                        <xsl:sort select="sum(//games/game/place[contains(., $nameOfPlace)]/following-sibling::score/number(substring-before(.,'-'))) div count(//games/game)" order="ascending" data-type="number"/>
                        <tr>
                            <td><xsl:value-of select="place"/></td>
                            <td><xsl:value-of select="sum(//games/game/place[contains(., $nameOfPlace)]/following-sibling::score/number(substring-before(.,'-'))) div count(//games/game)"/></td>
                            <td><xsl:value-of select="sum(//games/game/place[contains(., $nameOfPlace)]/following-sibling::score/number(substring-after(.,'-'))) div count(//games/game)"/></td>
                        </tr>
                    </xsl:for-each>

我该如何避免这种情况?

1 个答案:

答案 0 :(得分:0)

使用变量的一种方法是使用for在XPath表达式中声明变量:

<xsl:sort select="for $nameOfPlace in text(),
      $score in sum(//games/game/place[contains(., $nameOfPlace)]/
                     following-sibling::score/number(substring-before(.,'-')))
        return $score div $numOfGames"
   order="ascending" data-type="number"/>

这样的事情。 (未测试)。

是的,它很笨重。和 遗憾的是,这些变量在XPath表达式之外是不可用的。因此,如果要在排序后使用它们,则必须再次声明它们。在没有变量的情况下,上述内容是否有所改善。

<强>更新 关于做没有变量。

您无法确定如何删除nameOfPlace变量声明。怎么样:

<xsl:for-each select="//games/game/place">
  <xsl:sort select="sum(//games/game/place[contains(., current()/text())]/
        following-sibling::score/number(substring-before(.,'-')))
      div count(//games/game)"
    order="ascending" data-type="number"/>

current()允许您引用当前XPath表达式(sort select)的外部上下文项。在这种情况下,这将是<place>迭代的<xsl:-for-each>元素。