我需要创建一个模板,用于格式化包含高尔夫球手在球场上每个洞的得分的表格单元格...
以下是我编写的代码,但似乎陷入无限循环,我不确定我是否正确调用模板或问题是什么?
<xsl:template name="formatHole">
<xsl:param name="parScore" />
<xsl:param name="holeScore" select="0" />
<!-- Check to see if cells parameter is greater than 0-->
<xsl:choose>
<xsl:when test="$holeScore < $parScore">
<td class="low"><xsl:value-of select="$holeScore" /></td>
</xsl:when>
<xsl:when test="$holeScore > $parScore">
<td class="high"><xsl:value-of select="$holeScore" /></td>
</xsl:when>
<xsl:otherwise>
<td><xsl:value-of select="$holeScore" /></td>
</xsl:otherwise>
</xsl:choose>
<xsl:call-template name="formatHole">
<xsl:with-param name="parScore" select="$holeScore - 1" />
<xsl:with-param name="holeScore" select="$parScore" />
</xsl:call-template>
</xsl:template>
以下是xml代码的片段...
<course>
<par holeNumber="1">4</par>
<par holeNumber="2">4</par>
<par holeNumber="3">5</par>
<par holeNumber="4">3</par>
<par holeNumber="5">4</par>
<par holeNumber="6">4</par>
<par holeNumber="7">5</par>
<par holeNumber="8">3</par>
<par holeNumber="9">4</par>
<par holeNumber="10">4</par>
<par holeNumber="11">5</par>
<par holeNumber="12">4</par>
<par holeNumber="13">3</par>
<par holeNumber="14">4</par>
<par holeNumber="15">5</par>
<par holeNumber="16">4</par>
<par holeNumber="17">3</par>
<par holeNumber="18">4</par>
</course>
<golfer>
<name>Brett Bierson</name>
<round roundNumber="1">
<score holeNumber="1">4</score>
<score holeNumber="2">4</score>
<score holeNumber="3">5</score>
<score holeNumber="4">2</score>
<score holeNumber="5">4</score>
<score holeNumber="6">4</score>
<score holeNumber="7">5</score>
<score holeNumber="8">4</score>
<score holeNumber="9">4</score>
<score holeNumber="10">4</score>
<score holeNumber="11">3</score>
<score holeNumber="12">4</score>
<score holeNumber="13">3</score>
<score holeNumber="14">4</score>
<score holeNumber="15">5</score>
<score holeNumber="16">5</score>
<score holeNumber="17">3</score>
<score holeNumber="18">3</score>
</round>
答案 0 :(得分:3)
无需使用call-templates
执行此操作。您需要的所有信息都在每个节点上。你拥有的是a pull (rather than a push) XSLT template。对于每个score
,您需要知道的是,您需要针对该给定的孔号对par
进行检查,因此只需检查它。
在下面的模板中,除了在课程中搜索该洞的相应数据外,我们只是单独查看得分。这意味着我们如何对待得分与其他得分相同。
<xsl:template match="score">
<xsl:variable name="holeScore" select="." />
<xsl:variable name="holeNum" select="@holeNumber" />
<xsl:variable name="parScore" select="/data/course/par[@holeNumber = $holeNum]" />
<tr>
<td><xsl:value-of select="@holeNumber"/></td>
<xsl:choose>
<xsl:when test="$holeScore &lt; $parScore">
<td class="low"><xsl:value-of select="$holeScore" /></td>
</xsl:when>
<xsl:when test="$holeScore &gt; $parScore">
<td class="high"><xsl:value-of select="$holeScore" /></td>
</xsl:when>
<xsl:otherwise>
<td><xsl:value-of select="$holeScore" /></td>
</xsl:otherwise>
</xsl:choose>
</tr>
</xsl:template>
我们可以在渲染表时轻松调用此方法,只需使用apply-templates
获取高尔夫球手在其课程中所拥有的每个分数:
<xsl:template match="golfer">
<h2>Scores for <xsl:value-of select="name"/></h2>
<table>
<tr>
<td>Hole</td><td>Score</td>
</tr>
<xsl:apply-templates select="./round/score"/>
</table>
</xsl:template>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<html>
<head>
<style>
.low {
background-color:red;
}
.high {
background-color:green;
}
</style>
</head>
<body>
<xsl:apply-templates select="/data/golfer"/>
</body>
</html>
</xsl:template>
<xsl:template match="golfer">
<h2>Scores for <xsl:value-of select="name"/></h2>
<table>
<tr>
<td>Hole</td><td>Score</td>
</tr>
<xsl:apply-templates select="./round/score"/>
</table>
</xsl:template>
<xsl:template match="score">
<xsl:variable name="holeScore" select="." />
<xsl:variable name="holeNum" select="@holeNumber" />
<xsl:variable name="parScore" select="/data/course/par[@holeNumber = $holeNum]" />
<tr>
<td><xsl:value-of select="@holeNumber"/></td>
<xsl:choose>
<xsl:when test="$holeScore &lt; $parScore">
<td class="low"><xsl:value-of select="$holeScore" /></td>
</xsl:when>
<xsl:when test="$holeScore &gt; $parScore">
<td class="high"><xsl:value-of select="$holeScore" /></td>
</xsl:when>
<xsl:otherwise>
<td><xsl:value-of select="$holeScore" /></td>
</xsl:otherwise>
</xsl:choose>
</tr>
</xsl:template>
</xsl:stylesheet>
<data>
<course>
<par holeNumber="1">4</par>
<par holeNumber="2">4</par>
<par holeNumber="3">5</par>
<par holeNumber="4">3</par>
<par holeNumber="5">4</par>
<par holeNumber="6">4</par>
<par holeNumber="7">5</par>
<par holeNumber="8">3</par>
<par holeNumber="9">4</par>
<par holeNumber="10">4</par>
<par holeNumber="11">5</par>
<par holeNumber="12">4</par>
<par holeNumber="13">3</par>
<par holeNumber="14">4</par>
<par holeNumber="15">5</par>
<par holeNumber="16">4</par>
<par holeNumber="17">3</par>
<par holeNumber="18">4</par>
</course>
<golfer>
<name>Brett Bierson</name>
<round roundNumber="1">
<score holeNumber="1">4</score>
<score holeNumber="2">4</score>
<score holeNumber="3">5</score>
<score holeNumber="4">2</score>
<score holeNumber="5">4</score>
<score holeNumber="6">4</score>
<score holeNumber="7">5</score>
<score holeNumber="8">4</score>
<score holeNumber="9">4</score>
<score holeNumber="10">4</score>
<score holeNumber="11">3</score>
<score holeNumber="12">4</score>
<score holeNumber="13">3</score>
<score holeNumber="14">4</score>
<score holeNumber="15">5</score>
<score holeNumber="16">5</score>
<score holeNumber="17">3</score>
<score holeNumber="18">3</score>
</round>
</golfer>
</data>
<html>
<head>
<style>
.low {
background-color:red;
}
.high {
background-color:green;
}
</style>
</head>
<body>
<h2>Scores for Brett Bierson</h2>
<table>
<tr>
<td>Hole</td>
<td>Score</td>
</tr>
<tr>
<td>1</td>
<td>4</td>
</tr>
<tr>
<td>2</td>
<td>4</td>
</tr>
<tr>
<td>3</td>
<td>5</td>
</tr>
<tr>
<td>4</td>
<td class="low">2</td>
</tr>
<tr>
<td>5</td>
<td>4</td>
</tr>
<tr>
<td>6</td>
<td>4</td>
</tr>
<tr>
<td>7</td>
<td>5</td>
</tr>
<tr>
<td>8</td>
<td class="high">4</td>
</tr>
<tr>
<td>9</td>
<td>4</td>
</tr>
<tr>
<td>10</td>
<td>4</td>
</tr>
<tr>
<td>11</td>
<td class="low">3</td>
</tr>
<tr>
<td>12</td>
<td>4</td>
</tr>
<tr>
<td>13</td>
<td>3</td>
</tr>
<tr>
<td>14</td>
<td>4</td>
</tr>
<tr>
<td>15</td>
<td>5</td>
</tr>
<tr>
<td>16</td>
<td class="high">5</td>
</tr>
<tr>
<td>17</td>
<td>3</td>
</tr>
<tr>
<td>18</td>
<td class="low">3</td>
</tr>
</table>
</body>
</html>
答案 1 :(得分:0)
最后,您的模板会调用您的模板:
<xsl:template name="formatHole">
[...]
<xsl:call-template name="formatHole">
<xsl:with-param name="parScore" select="$holeScore - 1" />
<xsl:with-param name="holeScore" select="$parScore" />
</xsl:call-template>
</xsl:template>
这可以解释为什么它没有结束。与JavaScript中的方式相同:
function foo() {
foo();
}
不会结束。或者更有可能JavaScript版本以堆栈溢出结束。 XSLT代码没有结束,因为我认为XSLT解释器执行tail call optimization。 (它变成了迭代。)
答案 2 :(得分:-2)
我对高尔夫一无所知,所以我只是在这里猜测。看起来您想要为一轮中的每个分数创建一个单元格,并将其与课程中相应的holeNumber的par相比较。
您的模板存在一些问题:首先,您永远不会检查在0下运行的迭代器(尽管您确实有评论说您应该这样做)。接下来,您选择的holeScore作为迭代器是没有意义的:您需要从1到18进行迭代,而不是从4或5到0进行迭代。此外,在每次迭代时都要与相同的par进行比较。
现在,假设这是在一轮的上下文中完成的,你可以用更简单的方式完成。首先,将以下内容放在样式表的开头,在任何模板之外:
<xsl:key name="par" match="par" use="@holeNumber" />
接下来,在回合的背景下,执行以下操作:
<tr>
<td><xsl:value-of select="@roundNumber" /></td>
<xsl:call-template name="createCells"/>
</tr>
最后,这是被调用的模板:
<xsl:template name="createCells">
<xsl:for-each select="score">
<xsl:variable name="par" select="key('par', @holeNumber)" />
<xsl:choose>
<xsl:when test=". < $par">
<td class="low"><xsl:value-of select="." /></td>
</xsl:when>
<xsl:when test=". > $par">
<td class="high"><xsl:value-of select="." /></td>
</xsl:when>
<xsl:otherwise>
<td><xsl:value-of select="." /></td>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each>
</xsl:template>
请注意,这假设每一轮都有18个分数。如果这不是一个有效的假设,那么将需要使用带有迭代器的递归模板。