Re: [xsl] Keeping a running total? (Redo)

Subject: Re: [xsl] Keeping a running total? (Redo)
From: "Dimitre Novatchev" <dnovatchev@xxxxxxxxx>
Date: Tue, 11 Jul 2006 21:15:42 -0700
Here's one possible solution:

This transformation:

<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
xmlns:xs="http://www.w3.org/2001/XMLSchema";
xmlns:f="http://fxsl.sf.net/";
exclude-result-prefixes="f xs"

<xsl:import href="../f/func-scanl.xsl"/>
<xsl:import href="../f/func-Operators.xsl"/>
<xsl:import href="../f/func-map.xsl"/>

<!-- To be run against: ..\data\testFunc-Scanl2.xml -->

<xsl:output omit-xml-declaration="yes" indent="yes"/>

<xsl:param name="prunQuatas" as="element()+">
 <q name="widgets" min="1" max="8"/>
 <q name="gadgets" min="9" max="13"/>
 <q name="excess" min="14" max="999999999"/>
</xsl:param>

<xsl:template match="/">
   <xsl:variable name="vFactories" as="element()+"
    select="/*/*"/>

   <xsl:variable name="vrunTotals" as="xs:double+"
    select="f:scanl(f:add(), 0, $vFactories/@capacity)"/>

   <xsl:variable name="vMinInSeq" as="xs:double+" select=
    "f:map(f:add(1), $vrunTotals)"
    />

   <xsl:variable name="vMaxInSeq" as="xs:double+" select=
    "remove($vrunTotals,1), 999999999"
    />

   <xsl:sequence select=
    "for $ind in 1 to count($vFactories)
          return
           f:breakDownElement($ind,$vFactories,
                              $vMinInSeq, $vMaxInSeq,
                              $prunQuatas
                              )
    "
   />
</xsl:template>

<xsl:function name="f:breakDownElement" as="element()">
  <xsl:param name="pInd" as="xs:integer"/>
  <xsl:param name="pFactories" as="element()+"/>
  <xsl:param name="pMinInSeq" as="xs:double+"/>
  <xsl:param name="pMaxInSeq" as="xs:double+"/>
  <xsl:param name="prunQuatas" as="element()+"/>

<xsl:variable name="pFctry" select="$pFactories[$pInd]"/>

  <xsl:element name="{name($pFctry)}">
    <xsl:copy-of select="$pFctry/@*"/>
    <xsl:sequence select=
    "f:breakDown($pInd, $pMinInSeq, $pMaxInSeq, $prunQuatas)"/>
  </xsl:element>
</xsl:function>

<xsl:function name="f:breakDown">
  <xsl:param name="pInd" as="xs:integer"/>
  <xsl:param name="pMinInSeq" as="xs:double+"/>
  <xsl:param name="pMaxInSeq" as="xs:double+"/>
  <xsl:param name="prunQuatas" as="element()+"/>

  <xsl:variable name="vMin" as="xs:double"
    select="$pMinInSeq[$pInd]"/>

  <xsl:variable name="vMax" as="xs:double"
    select="$pMaxInSeq[$pInd]"/>

  <xsl:for-each select=
     "$prunQuatas[not($vMin > @max or @min > $vMax)]">

     <xsl:attribute name="{@name}" select=
      "min(($vMax, @max)) - max(($vMin, @min)) +1"/>
  </xsl:for-each>
</xsl:function>
</xsl:stylesheet>


when applied on this xml document


<xml>
<factory x="A" capacity = "3" />
<factory x="B" capacity= "6" />
<factory x="C" capacity = "3" />
<factory x="D" capacity = "2" />
<factory x="E" capacity = "2" />
...etc...
</xml>

produces the wanted result:

<factory x="A" capacity="3" widgets="3"/>
<factory x="B" capacity="6" widgets="5" gadgets="1"/>
<factory x="C" capacity="3" gadgets="3"/>
<factory x="D" capacity="2" gadgets="1" excess="1"/>
<factory x="E" capacity="2" excess="2"/>

--
Cheers,
Dimitre Novatchev
---------------------------------------
Truly great madness cannot be achieved without significant intelligence.


On 7/11/06, didoss@xxxxxxxxxxx <didoss@xxxxxxxxxxx> wrote:
I would think that the intended output would be:

Factory A produces 3 widgets;
Factory B produces 5 widgets and 1 gadget;
Factory C produces 3 gadgets;
Factory D produces 1 gadget and 1 excess product - whatever that is;
Factory E and beyond produce excess products.

So, you are really trying to keep track of 2 changing numbers,...the number of current product still required, as well as the capacity of the factory. When the number of the current product required gets to zero, you change products - gotta figure out how to prioritize those. When the capacity of the current factory gets to zero (has been fully allocated), you change factories - which would be controlled by the order of the input xml, I assume.

So, is it better to do this incrementally - subtract one from required and one from remaining capacity,...or to do bulk comparisons - I need to build 8, but can only build 3, so give all three to Factory 1, and subtract 3 from WidgetRequirement, then I still need to build 5, but Factory B can build 6, so subtract all 5 from the WidgetRequirement and the CurrentCapacity and then figure out what to do with the remaining CurrentCapacity for Factory B.


Dianne


 -------------- Original message ----------------------
From: "Dimitre Novatchev" <dnovatchev@xxxxxxxxx>
> The presented source xml file is not too representative because the
> total capacity of the first two factories is exactly the widget quota.
>
> What should be the output in case the capacity for factory B was 6?
>
>
> On 7/11/06, Steve <subsume@xxxxxxxxx> wrote:
> > Previous thread has degenerated into confusion. Let's try again.
> >
> > ----- Source XML
> > <xml>
> >  <factory x="A" capacity = "3" />
> >  <factory x="B" capacity= "5" />
> >   <factory x="C" capacity = "3" />
> >   <factory x="D" capacity = "2" />
> >   <factory x="E" capacity = "2" />
> >   ...etc...
> > </xml>
> >
> > $Widget_quota = "8"
> > $Gadget_quota = "5"
> >
> > ----- Goal: an output table like below.
> >
> > Factory    |   Widgets  |  Gadgets    |      Excess
> >
> >     A        |   3
> >     B        |   5
> > <!--          *Click. Widget Quota has been reached. Switch to gadgets* -->
> >     C        |                       3
> >     D        |                       2
> >  <!--          *Click. Omg. Gadget Quota has been reached. Switch to Excess*
> -->
> >     E         |                                             etc.
> >     F         |                                             etc.
> >     G         |                                             etc.
> >     H         |                                             etc.
> >
> > ----
> > Howto?
> >
> > M.K. Suggested
> > http://www.biglist.com/lists/xsl-list/archives/200607/msg00191.html
> > but my question (Howto?) remains.
> >
> > Thanks,
> >
> > -Steve
> >
> >
>
>
> --
> Cheers,
> Dimitre Novatchev
> ---------------------------------------
> Truly great madness cannot be achieved without significant intelligence.

Current Thread