当前位置: 动力学知识库 > 问答 > 编程问答 >

xml - How to autonumber table rows?

问题描述:

I want generate a column called "Position" and show the position of each driver (1, 2, 3) automatically. I try with <xsl:number /> but just show the position in the XML and I don't want that. Any ideas?

XSLT CODE:

<?xml version="1.0" encoding="UTF-8"?>

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

<xsl:output method="html" indent="yes" doctype-public="-//W3C//DTD XHTML 1.1//EN" doctype-system="http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd" />

<xsl:template match="/grid">

<html xmlns="http://www.w3.org/1999/xhtml" >

<body>

<table border="1" width="100%" align="center">

<tr>

<th colspan="5">Clasificación</th>

</tr>

<tr>

<th>Piloto</th>

<th>Total</th>

<th>Imola</th>

<th>Monza</th>

<th>Silverstone</th>

</tr>

<xsl:for-each select="driver">

<xsl:sort select="sum(points/*)" data-type="number" order="descending"/>

<tr>

<td><xsl:value-of select="name" /></td>

<td><xsl:value-of select="sum(points/*)" /></td>

<td><xsl:value-of select="points/imola" /></td>

<td><xsl:value-of select="points/monza" /></td>

<td><xsl:value-of select="points/silverstone" /></td>

</tr>

</xsl:for-each>

</table>

</body>

</html>

</xsl:template>

</xsl:stylesheet>

XML CODE:

<grid>

<driver>

<name>Driver A</name>

<points>

<imola>10</imola>

<monza>2</monza>

<silverstone>10</silverstone>

</points>

</driver>

<driver>

<name>Driver B</name>

<points>

<imola>9</imola>

<monza>6</monza>

<silverstone>7</silverstone>

</points>

</driver>

<driver>

<name>Driver C</name>

<points>

<imola>8</imola>

<monza>10</monza>

<silverstone>5</silverstone>

</points>

</driver>

</grid>

网友答案:

It depends on what exactly you mean by "position". You can use either;

<xsl:value-of select="position()" />

or:

<xsl:value-of select="count(../driver[sum(points/*) > sum(current()/points/*)]) + 1" />

The difference will be seen when two or more drivers have the same amount of points.


The second one is perfect, but I don't understand how it works. Can you explain it?

It counts the number of drivers that have more points than the current one.

  • If the driver is in the first place, then there are no drivers that have more points - and the result is 0 (and we add 1 to that ==> 1st);

  • If the driver is in the second place, then there is one driver that has more points - so the result is 1 (and we add 1 to that ==> 2nd);

  • If two drivers are in the second place, then for both of them there is exactly one driver that has more points - so they are both in 2nd place; the next driver has three drivers ahead of him, so he ends up being in 4th place - and no one is tagged as being 3rd.

Note that you could make this more efficient by storing the sum of points in a variable first, then use the variable in the two places in the table, e.g.:

<xsl:for-each select="driver">
    <xsl:sort select="sum(points/*)" data-type="number" order="descending"/>
    <xsl:variable name="pts" select="sum(points/*)" />
    <tr>
        <td><xsl:value-of select="count(../driver[sum(points/*) > $pts]) + 1" /></td>
        <td><xsl:value-of select="name" /></td>
        <td><xsl:value-of select="$pts" /></td>
        <td><xsl:value-of select="points/imola" /></td>
        <td><xsl:value-of select="points/monza" /></td>
        <td><xsl:value-of select="points/silverstone" /></td>
    </tr>
</xsl:for-each> 

Unfortunately, it's not possible to avoid calculating the same thing separately for the sort.

分享给朋友:
您可能感兴趣的文章:
随机阅读: