我在JMeter中运行了一系列的webservice测试,我想做的是获取每个测试返回的平均响应时间的总和。我有办法找到每个测试的平均响应时间,但无法将测试的平均值加在一起。我知道为了使用XPath的sum()函数,值必须是节点集的一部分,但是根据我的理解,一旦我找到XML中的平均值,它们就不再是其中的一部分了。所以我需要使用node-set()函数,但我对XSLT / XPath还不熟悉,并且不确定如何使事情正常工作。
对此有任何帮助表示赞赏!
这是来自JMeter的示例XML,运行了两次迭代:
<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="../style/jmeter-results-detail-report_21.xsl"?>
<testResults version="1.2">
<httpSample t="78" lt="78" ts="1338826079163" s="true" lb="html" rc="200" rm="OK" tn="vuserver 1-1" dt="text" by="4418" ng="1" na="1"/>
<httpSample t="31" lt="31" ts="1338826079241" s="true" lb="userRoleRetriever" rc="200" rm="OK" tn="vuserver 1-1" dt="text" by="758" ng="1" na="1"/>
<httpSample t="32" lt="32" ts="1338826079272" s="true" lb="UserActivityWSDL" rc="200" rm="OK" tn="vuserver 1-1" dt="text" by="2398" ng="1" na="1"/>
<httpSample t="156" lt="125" ts="1338826079304" s="true" lb="SubscriberMgmtWSDL" rc="200" rm="OK" tn="vuserver 1-1" dt="text" by="56434" ng="1" na="1"/>
<httpSample t="31" lt="16" ts="1338826079460" s="true" lb="NetworkMgmtWSDL" rc="200" rm="OK" tn="vuserver 1-1" dt="text" by="33020" ng="1" na="1"/>
<httpSample t="15" lt="15" ts="1338826079507" s="true" lb="AlarmMgmtWSDL" rc="200" rm="OK" tn="vuserver 1-1" dt="text" by="11594" ng="1" na="1"/>
<httpSample t="141" lt="141" ts="1338826079538" s="true" lb="getSubscribers" rc="200" rm="OK" tn="vuserver 1-1" dt="text" by="397" ng="1" na="1"/>
<httpSample t="265" lt="234" ts="1338826079679" s="true" lb="getMpegResultsById" rc="200" rm="OK" tn="vuserver 1-1" dt="text" by="832927" ng="1" na="1"/>
<httpSample t="15" lt="15" ts="1338826079976" s="true" lb="getOverallSummary" rc="200" rm="OK" tn="vuserver 1-1" dt="text" by="402" ng="1" na="1"/>
<httpSample t="0" lt="0" ts="1338826082663" s="true" lb="html" rc="200" rm="OK" tn="vuserver 1-2" dt="text" by="4418" ng="1" na="1"/>
<httpSample t="16" lt="16" ts="1338826082663" s="true" lb="userRoleRetriever" rc="200" rm="OK" tn="vuserver 1-2" dt="text" by="758" ng="1" na="1"/>
<httpSample t="15" lt="0" ts="1338826082679" s="true" lb="UserActivityWSDL" rc="200" rm="OK" tn="vuserver 1-2" dt="text" by="2398" ng="1" na="1"/>
<httpSample t="32" lt="0" ts="1338826082694" s="true" lb="SubscriberMgmtWSDL" rc="200" rm="OK" tn="vuserver 1-2" dt="text" by="56434" ng="1" na="1"/>
<httpSample t="31" lt="15" ts="1338826082726" s="true" lb="NetworkMgmtWSDL" rc="200" rm="OK" tn="vuserver 1-2" dt="text" by="33020" ng="1" na="1"/>
<httpSample t="16" lt="16" ts="1338826082757" s="true" lb="AlarmMgmtWSDL" rc="200" rm="OK" tn="vuserver 1-2" dt="text" by="11594" ng="1" na="1"/>
<httpSample t="250" lt="250" ts="1338826082788" s="true" lb="getSubscribers" rc="200" rm="OK" tn="vuserver 1-2" dt="text" by="10536" ng="1" na="1"/>
<httpSample t="15454" lt="15392" ts="1338826083038" s="true" lb="getMpegResultsById" rc="200" rm="OK" tn="vuserver 1-2" dt="text" by="2023426" ng="1" na="1"/>
<httpSample t="15" lt="15" ts="1338826098555" s="true" lb="getOverallSummary" rc="200" rm="OK" tn="vuserver 1-2" dt="text" by="402" ng="1" na="1"/>
</testResults>
这是我的XSLT中的一个exerpt,其中找到了每个测试的平均值。
<xsl:for-each select="/testResults/*[not(@lb = preceding::*/@lb)]">
...
<xsl:variable name="count" select="count(../*[@lb = current()/@lb])" />
<xsl:variable name="totalTime" select="sum(../*[@lb = current()/@lb]/@t)" />
<xsl:variable name="averageTime" select="$totalTime div $count" />
...
</xsl:for-each>
如何将这些平均时间输入节点集并随后求它们?
Here is an example of what the final reports look like for those interested
提前致谢!
答案 0 :(得分:1)
如果可以使用XSLT2.0,那么它具有处理节点集的内置功能,而在XSLT1.0中,您必须使用扩展功能。通过节点集,您可以创建一个变量,该变量包含(新创建的)节点的列表,然后您可以迭代它们,甚至可以对它们求和,就好像它们是源文档本身一样。 / p>
在展示解决方案之前需要注意的另一件事是,这也是分组问题的一个例子。您有多个测试的结果,并希望按名称对它们进行分组。您当前使用的方法不一定有效。在XSLT2.0中虽然有 xsl:for-each-group 函数可以让事情变得更容易
<xsl:for-each-group select="httpSample" group-by="@lb">
您需要做的是创建变量,并通过对测试结果进行分组并添加“平均值”来构建新的节点集。节点到新列表。
<xsl:variable name="results">
<xsl:for-each-group select="httpSample" group-by="@lb">
<xsl:variable name="count" select="count(current-group())"/>
<xsl:variable name="totalTime" select="sum(current-group()/@t)"/>
<test lb="{current-grouping-key()}" num="{$count}" tot="{$totalTime}" avg="{$totalTime div $count}"/>
</xsl:for-each-group>
</xsl:variable>
因此,此处的结果变量将包含 test 元素的列表,每个不同的测试一个元素,新添加的节点具有平均时间。然后,您可以迭代这些结果,甚至将它们相加。
这是完整的XSLT
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html" indent="yes"/>
<xsl:template match="/testResults">
<xsl:variable name="results">
<xsl:for-each-group select="httpSample" group-by="@lb">
<xsl:variable name="count" select="count(current-group())"/>
<xsl:variable name="totalTime" select="sum(current-group()/@t)"/>
<test lb="{current-grouping-key()}" num="{$count}" tot="{$totalTime}" avg="{$totalTime div $count}"/>
</xsl:for-each-group>
</xsl:variable>
<table>
<tr>
<th>Test</th>
<th>Total Test</th>
<th>Total Time</th>
<th>Average Time</th>
</tr>
<xsl:for-each select="$results/test">
<tr>
<td>
<xsl:value-of select="@lb"/>
</td>
<td>
<xsl:value-of select="@num"/>
</td>
<td>
<xsl:value-of select="@tot"/>
</td>
<td>
<xsl:value-of select="@avg"/>
</td>
</tr>
</xsl:for-each>
<tr>
<td>Total</td>
<td>
<xsl:value-of select="sum($results/test/@num)"/>
</td>
<td>
<xsl:value-of select="sum($results/test/@tot)"/>
</td>
<td>
<xsl:value-of select="sum($results/test/@avg)"/>
</td>
</tr>
</table>
</xsl:template>
</xsl:stylesheet>
当应用于XML样本时,输出以下内容
<table>
<tr>
<th>Test</th>
<th>Total Test</th>
<th>Total Time</th>
<th>Average Time</th>
</tr>
<tr>
<td>html</td>
<td>2</td>
<td>78</td>
<td>39</td>
</tr>
<tr>
<td>userRoleRetriever</td>
<td>2</td>
<td>47</td>
<td>23.5</td>
</tr>
<tr>
<td>UserActivityWSDL</td>
<td>2</td>
<td>47</td>
<td>23.5</td>
</tr>
<tr>
<td>SubscriberMgmtWSDL</td>
<td>2</td>
<td>188</td>
<td>94</td>
</tr>
<tr>
<td>NetworkMgmtWSDL</td>
<td>2</td>
<td>62</td>
<td>31</td>
</tr>
<tr>
<td>AlarmMgmtWSDL</td>
<td>2</td>
<td>31</td>
<td>15.5</td>
</tr>
<tr>
<td>getSubscribers</td>
<td>2</td>
<td>391</td>
<td>195.5</td>
</tr>
<tr>
<td>getMpegResultsById</td>
<td>2</td>
<td>15719</td>
<td>7859.5</td>
</tr>
<tr>
<td>getOverallSummary</td>
<td>2</td>
<td>30</td>
<td>15</td>
</tr>
<tr>
<td>Total</td>
<td>18</td>
<td>16593</td>
<td>8296.5</td>
</tr>
</table>