This is the mail archive of the
xsl-list@mulberrytech.com
mailing list .
Re: Filtering Numeric Output with Changing Parameter
- From: Dimitre Novatchev <dnovatchev at yahoo dot com>
- To: xsl-list at lists dot mulberrytech dot com
- Date: Fri, 19 Jul 2002 22:41:00 -0700 (PDT)
- Subject: [xsl] Re: Filtering Numeric Output with Changing Parameter
- Reply-to: xsl-list at lists dot mulberrytech dot com
--- Tim Lewis <lewist at bit-sys dot com> wrote:
> I'd like to take a pile of numeric data and filter it down to a
> smaller
> pile by selecting for output only values that change by more than a
> threshold amount from the beginning value. If a value gets selected
> for
>
> output, then the next output value would have to be different from it
> by
>
> more than the threshold. For example, say I have a pile of stock
> price
> data and I want to plot only values that change by more than 1.00.
> If
> the first value is 27.50, then I want to look through the data and
> ignore it until I find a price >= 28.50 or <= 26.50. If I find a
> price
> of 28.50, then I want to continue my search, but now I am looking for
> prices >= 29.50 or <= 27.50.
>
>
> So given:
>
> <stock>
> <time>0.0</time>
> <price>27.50</price>
> </stock>
> <stock>
> <time>1.0</time>
> <price>27.75</price>
> </stock>
> <stock>
> <time>3.0</time>
> <price>27.20</price>
> </stock>
> <stock>
> <time>4.0</time>
> <price>28.50</price>
> </stock>
> <stock>
> <time>5.0</time>
> <price>28.25</price>
> </stock>
> <stock>
> <time>6.0</time>
> <price>27.75</price>
> </stock>
> <stock>
> <time>7.0</time>
> <price>27.80</price>
> </stock>
> <stock>
> <time>8.0</time>
> <price>25.50</price>
> </stock>
>
> I want:
>
> <stock>
> <time>0.0</time>
> <price>27.50</price>
> </stock>
> <stock>
> <time>4.0</time>
> <price>28.50</price>
> </stock>
> <stock>
> <time>8.0</time>
> <price>25.50</price>
> </stock>
>
> I understand that I cannot use a for-each loop because the value of
> my
> comparison "variables" needs to be variable. I also understand that
> I
> need to use recursion to do it. However, I struggle mightily with
> procedural programming, so functional programming and recursion chew
> me
> up and spit me out.
>
> Any guidance would be appreciated. An actual named template to get
> this
>
> job done would be even more wondeful!
Hi Tim,
Using the folfl() function/template from FXSL it is quite easy:
testFoldl3.xsl:
--------------
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:foldl-func="f:foldl-func"
exclude-result-prefixes="xsl foldl-func"
>
<xsl:import href="foldl.xsl"/>
<xsl:output omit-xml-declaration="yes" />
<!-- This transformation must be applied to:
stocks.xml
-->
<foldl-func:foldl-func/>
<xsl:variable name="vFoldlFun"
select="document('')/*/foldl-func:*[1]"/>
<xsl:variable name="vTolerance" select="1"/>
<xsl:template match="/">
<xsl:call-template name="foldl">
<xsl:with-param name="pFunc" select="$vFoldlFun"/>
<xsl:with-param name="pList" select="/*/stock[position() >
1]"/>
<xsl:with-param name="pA0" select="/*/stock[1]"/>
</xsl:call-template>
</xsl:template>
<xsl:template match="foldl-func:*">
<xsl:param name="arg1" select="/.."/> <!-- pA0 (accumulator) -->
<xsl:param name="arg2" select="/.."/>
<xsl:variable name="vLastPrice" select="$arg1[last()]/price"/>
<xsl:variable name="vCurPrice" select="$arg2/price"/>
<xsl:variable name="vChange"
select="$arg1[last()]/price - $arg2/price"/>
<xsl:copy-of select="$arg1"/>
<xsl:if test="$vChange >= $vTolerance
or
$vChange <= -$vTolerance" >
<xsl:copy-of select="$arg2"/>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
When applied on your source xml:
stocks.xml:
----------
<stocks>
<stock>
<time>0.0</time>
<price>27.50</price>
</stock>
<stock>
<time>1.0</time>
<price>27.75</price>
</stock>
<stock>
<time>3.0</time>
<price>27.20</price>
</stock>
<stock>
<time>4.0</time>
<price>28.50</price>
</stock>
<stock>
<time>5.0</time>
<price>28.25</price>
</stock>
<stock>
<time>6.0</time>
<price>27.75</price>
</stock>
<stock>
<time>7.0</time>
<price>27.80</price>
</stock>
<stock>
<time>8.0</time>
<price>25.50</price>
</stock>
</stocks>
The result is:
<stock>
<time>0.0</time>
<price>27.50</price>
</stock><stock>
<time>4.0</time>
<price>28.50</price>
</stock><stock>
<time>8.0</time>
<price>25.50</price>
</stock>
Hope this helped.
=====
Cheers,
Dimitre Novatchev.
http://fxsl.sourceforge.net/ -- the home of FXSL
__________________________________________________
Do You Yahoo!?
Yahoo! Health - Feel better, live better
http://health.yahoo.com
XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list