有没有办法在XSLT 2.0中计算简单移动平均线?例如,我将有一个XML文档,其中有100个值,但是在XSLT之后的某个函数(SMA)只给出了50个值作为输出。
感谢您的所有想法
修改
我添加了一些例子,你可以看到我有XML文档,我每个月都有一个品牌三星的价格。现在我想只有2个价格值(第5个月和第10个月,如下图所示)。
这是一些XML文档
addFirst()
这是想要的结果
<?xml version="1.0" encoding="UTF-8"?>
<trade>
<phone month="1" brand="samsung">
<price>1000</price>
</phone>
<phone month="2" brand="samsung">
<price>890</price>
</phone>
<phone month="3" brand="samsung">
<price>870</price>
</phone>
<phone month="4" brand="samsung">
<price>950</price>
</phone>
<phone month="5" brand="samsung">
<price>920</price>
</phone>
<phone month="6" brand="samsung">
<price>930</price>
</phone>
<phone month="7" brand="samsung">
<price>870</price>
</phone>
<phone month="8" brand="samsung">
<price>830</price>
</phone>
<phone month="9" brand="samsung">
<price>910</price>
</phone>
<phone month="10" brand="samsung">
<price>950</price>
</phone>
</trade>
答案 0 :(得分:4)
最简单的方法是为每个项目计算最后50个值的平均值:
<xsl:template match="trade">
<sma50>
<xsl:value-of select="avg((@price,
preceding-sibling::trade[position() lt 50]/@price))"/>
</sma50>
</xsl:template>
这当然涉及每个项目的一些冗余计算。如果你想避免这种冗余计算,这是可能的,但代码将会相当棘手。第N项(N> 50)的滚动平均值是第(N-1)项的滚动平均值加上第N个值和第(N-50)个值之差除以50.所以你可以做到使用兄弟递归进行计算,其中在处理完一个项目之后,然后调用模板来处理其后续的兄弟,将当前的滚动平均值作为参数传递。但我非常怀疑性能提升值得额外麻烦。
您已更新问题:在修订版中,它似乎不是移动平均线,而更像是周期性平均值。如果您想报告每组连续5个月的平均值,您可以这样做:
<xsl:for-each-group select="trade/phone" group-adjacent="@month idiv 5">
<month nr="{current-group()[last()]/@month}"
avg-price="{avg(current-group()/@price)}"/>
</xsl:for-each-group>
答案 1 :(得分:0)
我是通过递归http://xsltfiddle.liberty-development.net/6qVRKvN/1完成的。它工作正常,结果就像在相关的链接。但是还有一件事没有用,如果样本默认情况下没有按日期排序。因此,如果样本是随机排序的,则结果不正确。如何按日期对样本进行排序,然后使用SMA?