[XSL-LIST Mailing List Archive Home] [By Thread] [By Date] [Recent Entries] [Reply To This Message]

Calculating cumulative values - another call for help

Subject: Calculating cumulative values - another call for help
From: "Simon Shutter" <simon@xxxxxxxxxxx>
Date: Wed, 29 Aug 2007 00:05:11 -0700
 Calculating cumulative values - another call for help
Dear Experts,

I've been aggregating numbers in XSLT 1.0 using the preceding-sibling:: axis
for nodes with the same parent.  I now need to aggregate all the values that
precede the context node, even if they have different parents.  For this I
added another attribute using the preceding:: axis (see XSLT 1.0 Stylesheet
below).  Unfortunately, the transform is starting to groan under the weight
of all these O(n^2) operations.  I have revisited an earlier solution
suggested by Dimitre Novatchev (see XSLT 2.0 Stylesheet below) that uses
FXSL.  However, I'm not clear how I can adapt it to meet the new
requirements.  Specifically, I would like to:

a) generate attribute y3 that is a cumulative value based on all preceding
<point> elements
b) copy y1 from the input to the output

Sincerely, Simon


---------------------------------------------
XSLT 2.0 Stylesheet 
---------------------------------------------
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:f="http://fxsl.sf.net/"
 exclude-result-prefixes="f">
  <xsl:import href="fxsl-xslt2/f/func-scanlDVC.xsl"/>
  <xsl:import href="fxsl-xslt2/f/func-Operators.xsl"/>

  <xsl:template match="node()|@*">
    <xsl:copy>
      <xsl:apply-templates select="node()|@*"/>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="set">
    <xsl:copy>
      <xsl:copy-of select="@*"/>
      <xsl:for-each-group select="point" group-by="@x">
         <xsl:sort select="current-grouping-key()" data-type="number"/>
         <xsl:for-each select="f:scanl1(f:add(), current-group()/@y1)">
            <point x="{current-group()[1]/@x}" y2="{.}"/>
         </xsl:for-each>
      </xsl:for-each-group>
    </xsl:copy>
 </xsl:template>

</xsl:stylesheet>


---------------------------------------------
XSLT 1.0 Stylesheet
---------------------------------------------
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:template match="node()|@*">
  <xsl:copy>
    <xsl:apply-templates select="node()|@*"/>
  </xsl:copy>
</xsl:template>

<xsl:template match="point">
 <xsl:copy>
   <xsl:copy-of select="@*"/>
   <xsl:attribute name="y2">
     <xsl:value-of select="sum(./@y1|preceding-sibling::point[@x =
current()/@x]/@y1)"/>
   </xsl:attribute>
   <xsl:attribute name="y3">
     <xsl:value-of select="sum(./@y1|preceding::point[@x =
current()/@x]/@y1)"/>
   </xsl:attribute>
 </xsl:copy>
</xsl:template>

</xsl:stylesheet>

---------------------------------------------
Input
---------------------------------------------

<root id="theroot">
  <set id="1">
    <point x="1" y1="2" />
    <point x="1" y1="3" />
    <point x="1" y1="0" />
    <point x="1" y1="2" />
    <point x="1" y1="2" />
    <point x="2" y1="3" />
    <point x="2" y1="0" />
    <point x="2" y1="2" />
    <point x="3" y1="2" />
    <point x="3" y1="3" />
    <point x="3" y1="1" />
    <point x="3" y1="2" />
    <point x="3" y1="2" />
  </set>
  <set id="2">
    <point x="1" y1="2" />
    <point x="1" y1="3" />
    <point x="1" y1="0" />
    <point x="1" y1="2" />
    <point x="2" y1="2" />
    <point x="3" y1="2" />
    <point x="3" y1="2" />
    <point x="3" y1="2" />
  </set>
  <set id="n">
    <point x="1" y1="2" />
    <point x="1" y1="3" />
    <point x="1" y1="2" />
    <point x="2" y1="3" />
    <point x="2" y1="0" />
    <point x="2" y1="2" />
    <point x="3" y1="3" />
  </set>
</root>

---------------------------------------------
Desired Output
---------------------------------------------

<root id="theroot">
  <set id="1">
    <point x="1" y1="2" y2="2" y3="2"/>
    <point x="1" y1="3" y2="5" y3="5"/>
    <point x="1" y1="0" y2="5" y3="5"/>
    <point x="1" y1="2" y2="7" y3="7"/>
    <point x="1" y1="2" y2="9" y3="9"/>
    <point x="2" y1="3" y2="3" y3="3"/>
    <point x="2" y1="0" y2="3" y3="3"/>
    <point x="2" y1="2" y2="5" y3="5"/>
    <point x="3" y1="2" y2="2" y3="2"/>
    <point x="3" y1="3" y2="5" y3="5"/>
    <point x="3" y1="1" y2="6" y3="6"/>
    <point x="3" y1="2" y2="8" y3="8"/>
    <point x="3" y1="2" y2="10" y3="10"/>
  </set>
  <set id="2">
    <point x="1" y1="2" y2="2" y3="11"/>
    <point x="1" y1="3" y2="5" y3="14"/>
    <point x="1" y1="0" y2="5" y3="14"/>
    <point x="1" y1="2" y2="7" y3="16"/>
    <point x="2" y1="2" y2="2" y3="7"/>
    <point x="3" y1="2" y2="2" y3="12"/>
    <point x="3" y1="2" y2="4" y3="14"/>
    <point x="3" y1="2" y2="6" y3="16"/>
  </set>
  <set id="n">
    <point x="1" y1="2" y2="2" y3="18"/>
    <point x="1" y1="3" y2="5" y3="21"/>
    <point x="1" y1="2" y2="7" y3="23"/>
    <point x="2" y1="3" y2="3" y3="10"/>
    <point x="2" y1="0" y2="3" y3="10"/>
    <point x="2" y1="2" y2="5" y3="12"/>
    <point x="3" y1="3" y2="3" y3="19"/>
  </set>
</root>

Current Thread

PURCHASE STYLUS STUDIO ONLINE TODAY!

Purchasing Stylus Studio from our online shop is Easy, Secure and Value Priced!

Buy Stylus Studio Now

Download The World's Best XML IDE!

Accelerate XML development with our award-winning XML IDE - Download a free trial today!

Don't miss another message! Subscribe to this list today.
Email
First Name
Last Name
Company
Subscribe in XML format
RSS 2.0
Atom 0.3
Site Map | Privacy Policy | Terms of Use | Trademarks
Free Stylus Studio XML Training:
W3C Member
Stylus Studio® and DataDirect XQuery ™are products from DataDirect Technologies, is a registered trademark of Progress Software Corporation, in the U.S. and other countries. © 2004-2013 All Rights Reserved.