This is the mail archive of the xsl-list@mulberrytech.com mailing list .


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Filtering Numeric Output with Changing Parameter


--- 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 &lt;= -$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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]