1

有人可以解释为什么以下不起作用。

这是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>

我想计算测试总数,总通过和失败。我在获取失败总数(失败 + 错误)和通过总数(为简单起见:测试 - 失败)时遇到问题。我使用“with-param”调用相同的 xml 模板来计算传入不同值的总计,如下所示(“计算总和”注释中的部分):

<?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”的“选择”接受“定义参数值的 XPath 表达式”(来自 w3schools)。XPath 表达式可以包含算术运算 ( http://www.w3schools.com/xpath/xpath_operators.asp ),那么为什么上面会失败呢?

这是 xsl 转换的完整输出:

测试区域总通过失败错误失败和错误
-------------------------------------------------- --------------------
test_ui_orchestration 10 10 0 0 0
test_ui_tables 13 12 0 1 1   
test_ui_dashboard 18 15 3 0 3
-------------------------------------------------- --------------------  
所有测试 41 foo 3 1 0

这是 xsl 转换的预期输出(用 * 标记的修改值):

测试区域总通过失败错误失败和错误
-------------------------------------------------- --------------------
test_ui_orchestration 10 10 0 0 0
test_ui_tables 13 12 0 1 1   
test_ui_dashboard 18 15 3 0 3
-------------------------------------------------- --------------------  
所有测试 41 37* 3 1 4*
4

3 回答 3

2

正如 Stormtroopr 所说,您没有向我们展示设置上下文的 XSLT 代码部分,而您将其省略的事实表明您还没有理解上下文在 XSLT 中的重要性。如果您的 XPath 表达式选择了任何内容,我们可能会假设上下文项是 testsuites 元素,在这种情况下,路径表达式(如testsuite/@failuresall 选择多个值)(包含多个属性节点的节点集)。如果您调用的模板需要一个节点集,那很好。但是,当您使用包含多个节点的节点集作为算术运算的输入时,则:

(a) 在 XSLT 1.0 中,它使用节点集中的第一个节点并忽略其他节点

(b) 在 XSLT 2.0 中,您会收到一个类型错误,说明您所做的事情没有意义。

由于您遇到错误,我假设您使用的是 XSLT 2.0,尽管它似乎不是一个很有帮助的错误消息(您使用的是哪个 XSLT 处理器?)

至于解决问题,我无能为力,因为您没有解释您要实现的目标 - 我无法从不正确的代码中对需求进行逆向工程。

于 2013-11-13T08:23:29.077 回答
0

不幸的是,您只发布了 XSLT 的片段,但我相信问题在于您是testsuite/@failurestestsuites元素调用的。

这不是返回一个数字,而是返回一个结果树片段或节点集,其中包含failures每个testsuite元素的属性值。

因此,传统的数字操作失败了,因为他们期望一个数字并获得一个 RTF 或节点集,并尝试应用该操作给出意外结果。

在不知道其余代码是什么的情况下,我建议修复的方法是将变量实例化包装在一个for-each循环中,或者甚至更好地包装在一个匹配个人的模板中testsuite

于 2013-11-13T03:13:19.600 回答
0

由于问题发生了巨大变化,我已经做出了新的答案。

您的求和模板(实际上是大部分模板)工作正常。您需要做的就是将这些总数放在底部,您只需对已创建的变量执行加法/减法:

<xsl:variable name="failederrorSum" select="$failedSum + $errorSum" />
<xsl:variable name="passedSum" select="$allSum - $failederrorSum" />

此样式表应用于输入 XML:

<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>

看起来像这样:

测试结果截图

于 2013-11-13T23:06:28.850 回答