有人可以解释为什么以下情况不起作用。
这是xml:
<?xml version="1.0" ?>
<testsuites>
<testsuite errors="0" failures="0" name="test_ui_orchestration" tests="10" time="90.190"/>
<testsuite errors="1" failures="0" name="test_ui_tables" tests="13" time="1115.771"/>
<testsuite errors="0" failures="3" name="test_ui_dashboard" tests="18" time="116.397"/>
</testsuites>
我想计算总测试次数,总次数和失败次数。我有一个问题是获得失败总数(失败+错误)和总传递次数(为简单起见:测试 - 失败)。我调用相同的xml-template来计算使用“with-param”传递不同值的总数,如下所示(“计算总和”注释中的部分):
<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/testsuites">
<html>
<body>
<!-- Calculate sums start -->
<xsl:variable name="allSum">
<xsl:call-template name="testsSum">
<xsl:with-param name="numTests" select="testsuite/@tests"/>
</xsl:call-template>
</xsl:variable>
<xsl:variable name="failedSum">
<xsl:call-template name="testsSum">
<xsl:with-param name="numTests" select="testsuite/@failures"/>
</xsl:call-template>
</xsl:variable>
<xsl:variable name="errorSum">
<xsl:call-template name="testsSum">
<xsl:with-param name="numTests" select="testsuite/@errors"/>
</xsl:call-template>
</xsl:variable>
<xsl:variable name="failederrorSum">
<xsl:call-template name="testsSum">
<xsl:with-param name="numTests" select="testsuite/@failures + testsuite/@errors"/>
</xsl:call-template>
</xsl:variable>
<!-- Calculate sums ends -->
<h2>Test Results</h2>
<table border="1">
<tr bgcolor="#9acd32">
<th>Test Area</th>
<th>Total</th>
<th>Pass</th>
<th>Fail</th>
<th>Error</th>
<th>Fail and Error</th>
</tr>
<xsl:for-each select="testsuite">
<tr>
<td><xsl:value-of select="@name"/></td>
<td><xsl:value-of select="@tests"/></td>
<td><xsl:value-of select="@tests - (@failures + @errors)"/></td>
<td><xsl:value-of select="@failures"/></td>
<td><xsl:value-of select="@errors"/></td>
<td><xsl:value-of select="@failures + @errors"/></td>
<td> </td>
</tr>
</xsl:for-each>
<tr>
<td><b>All Tests</b></td>
<td><xsl:value-of select="$allSum"/></td>
<td>foo</td>
<!--
<td><xsl:value-of select="$passedSum"/></td>
-->
<td><xsl:value-of select="$failedSum"/></td>
<td><xsl:value-of select="$errorSum"/></td>
<td><xsl:value-of select="$failederrorSum"/></td>
<td></td>
</tr>
</table>
</body>
</html>
</xsl:template>
<xsl:template name="testsSum">
<xsl:param name="numTests"/>
<xsl:choose>
<xsl:when test="$numTests">
<xsl:variable name="recursive_result">
<xsl:call-template name="testsSum">
<xsl:with-param name="numTests" select="$numTests[position() > 1]"/>
</xsl:call-template>
</xsl:variable>
<xsl:value-of select="number($numTests[1]) + $recursive_result"/>
</xsl:when>
<xsl:otherwise><xsl:value-of select="0"/></xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
这会为总和产生以下输出(完整输出在本文结尾处):
41 3 1 0
虽然它应该是:
41 3 1 4
每个单独的和工作正常,找到相应的属性。但是,当我尝试添加两个属性并将其传递给sum模板时,它无法按预期工作。
情况变得更糟。生成总测试的代码是:
<xsl:variable name="passedSum">
<xsl:call-template name="testsSum">
<xsl:with-param name="numTests"
select="testsuite/@tests - testsuite/@failures"/>
</xsl:call-template>
</xsl:variable>
启用上述代码后,出现以下错误:
Failed to evaluate the expression of variable 'numTests'
我一直在网上搜索并了解“with-param”的“select”接受“定义参数值的XPath表达式”(来自w3schools)。 XPath表达式可以包含算术运算(http://www.w3schools.com/xpath/xpath_operators.asp),那么为什么上面的失败呢?
这是xsl转换的完整输出:
Test Area Total Pass Fail Error Fail and Error ---------------------------------------------------------------------- test_ui_orchestration 10 10 0 0 0 test_ui_tables 13 12 0 1 1 test_ui_dashboard 18 15 3 0 3 ---------------------------------------------------------------------- All Tests 41 foo 3 1 0
以下是xsl转换的预期输出(标有*的修改值):
Test Area Total Pass Fail Error Fail and Error ---------------------------------------------------------------------- test_ui_orchestration 10 10 0 0 0 test_ui_tables 13 12 0 1 1 test_ui_dashboard 18 15 3 0 3 ---------------------------------------------------------------------- All Tests 41 37* 3 1 4*
答案 0 :(得分:2)
正如Stormtroopr所说,你没有向我们展示设置上下文的XSLT代码部分,而你遗漏了这一事实表明你还没有理解上下文在XSLT中的重要性。如果您的XPath表达式完全选择任何内容,我们可以假设上下文项是testsuites元素,在这种情况下,路径表达式(如testsuite/@failures
)都选择多个值(包含多个属性节点的节点集)。如果您调用的模板需要节点集,那就没问题。但是当您使用包含多个节点的节点集作为算术运算的输入时,则:
(a)在XSLT 1.0中,它使用节点集中的第一个节点而忽略其他节点
(b)在XSLT 2.0中,您会收到一个类型错误,说明您正在做的事情毫无意义。
由于您收到错误,我假设您使用的是XSLT 2.0,但它似乎不是一个非常有用的错误消息(您使用的是哪个XSLT处理器?)
至于解决问题,我无法解决这个问题,因为你没有解释你想要实现的目标 - 我无法对错误代码的要求进行逆向工程。
答案 1 :(得分:0)
不幸的是,您只发布了XSLT的片段,但我认为问题在于您是从testsuite/@failures
元素调用testsuites
。
而不是返回一个数字,而是返回结果树片段或节点集,其中包含每个failures
元素的testsuite
属性的值。
因此传统的数字操作失败了,因为他们期望一个数字并获得一个RTF或节点集,并尝试应用操作产生意外结果。
在不知道代码的其余部分是什么的情况下,我建议修复的方法是将变量实例化包装在for-each
循环中,甚至更好地包装在与个人匹配的模板中{ {1}}。
答案 2 :(得分:0)
由于问题发生了巨大变化,我已经做出了新的答案。
您的求和模板(实际上大部分模板)都可以正常工作。所有你需要做的就是将这些总数降到最低点,你只需要对你已经创建的变量进行加/减:
<xsl:variable name="failederrorSum" select="$failedSum + $errorSum" />
<xsl:variable name="passedSum" select="$allSum - $failederrorSum" />
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/testsuites">
<html>
<body>
<!-- Calculate sums start -->
<xsl:variable name="allSum">
<xsl:call-template name="testsSum">
<xsl:with-param name="numTests" select="testsuite/@tests"/>
</xsl:call-template>
</xsl:variable>
<xsl:variable name="failedSum">
<xsl:call-template name="testsSum">
<xsl:with-param name="numTests" select="testsuite/@failures"/>
</xsl:call-template>
</xsl:variable>
<xsl:variable name="errorSum">
<xsl:call-template name="testsSum">
<xsl:with-param name="numTests" select="testsuite/@errors"/>
</xsl:call-template>
</xsl:variable>
<xsl:variable name="failederrorSum" select="$failedSum + $errorSum" />
<xsl:variable name="passedSum" select="$allSum - $failederrorSum" />
<!-- Calculate sums ends -->
<h2>Test Results</h2>
<table border="1">
<tr bgcolor="#9acd32">
<th>Test Area</th>
<th>Total</th>
<th>Pass</th>
<th>Fail</th>
<th>Error</th>
<th>Fail and Error</th>
</tr>
<xsl:apply-templates />
<tr>
<td><b>All Tests</b></td>
<td><xsl:value-of select="$allSum"/></td>
<td><xsl:value-of select="$passedSum"/></td>
<td><xsl:value-of select="$failedSum"/></td>
<td><xsl:value-of select="$errorSum"/></td>
<td><xsl:value-of select="$failederrorSum"/></td>
<td></td>
</tr>
</table>
</body>
</html>
</xsl:template>
<xsl:template match="testsuite">
<tr>
<td><xsl:value-of select="@name"/></td>
<td><xsl:value-of select="@tests"/></td>
<td><xsl:value-of select="@tests - (@failures + @errors)"/></td>
<td><xsl:value-of select="@failures"/></td>
<td><xsl:value-of select="@errors"/></td>
<td><xsl:value-of select="@failures + @errors"/></td>
<td> </td>
</tr>
</xsl:template>
<xsl:template name="testsSum">
<xsl:param name="numTests"/>
<xsl:choose>
<xsl:when test="$numTests">
<xsl:variable name="recursive_result">
<xsl:call-template name="testsSum">
<xsl:with-param name="numTests" select="$numTests[position() > 1]"/>
</xsl:call-template>
</xsl:variable>
<xsl:value-of select="number($numTests[1]) + $recursive_result"/>
</xsl:when>
<xsl:otherwise><xsl:value-of select="0"/></xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
<html>
<body>
<h2>Test Results</h2>
<table border="1">
<tr bgcolor="#9acd32">
<th>Test Area</th>
<th>Total</th>
<th>Pass</th>
<th>Fail</th>
<th>Error</th>
<th>Fail and Error</th>
</tr>
<tr>
<td>test_ui_orchestration</td>
<td>10</td>
<td>10</td>
<td>0</td>
<td>0</td>
<td>0</td>
<td>
</td>
</tr>
<tr>
<td>test_ui_tables</td>
<td>13</td>
<td>12</td>
<td>0</td>
<td>1</td>
<td>1</td>
<td>
</td>
</tr>
<tr>
<td>test_ui_dashboard</td>
<td>18</td>
<td>15</td>
<td>3</td>
<td>0</td>
<td>3</td>
<td>
</td>
</tr>
<tr>
<td>
<b>All Tests</b>
</td>
<td>41</td>
<td>37</td>
<td>3</td>
<td>1</td>
<td>4</td>
<td/>
</tr>
</table>
</body>
</html>