Subject: [xsl] Re: Grouping problem? From: "Dimitre Novatchev" <dnovatchev@xxxxxxxxx> Date: Tue, 22 Apr 2003 23:18:47 +0200 |
Unfortunately, this does not produce the right result in the general case. Consider: <root> <ele sum="3"/> <ele sum="4"/> <ele sum="2"/> <ele sum="10"/> <ele sum="1"/> <ele sum="5"/> <ele sum="1"/> <ele sum="2"/> </root> The result produced by your transformation is: <root> <ele sum="3"></ele> <ele sum="4"></ele> <ele sum="2"></ele> <br /> <ele sum="10"></ele> <ele sum="1"></ele> <br /> <ele sum="5"></ele> <ele sum="1"></ele> <ele sum="2"></ele> </root> The second group above has a sum of 11. There is a recursive solution. It can be obtained by translating in XSLT the following brief Haskell solution: > cutBy :: (Num a, Ord a) => a -> [[a]] -> [a] -> [[a]] > cutBy z yss [] = yss > cutBy z (yss) (x:xs) > | sum (last yss) + x < z + 1 = cutBy z ( init yss ++ [last yss ++ [x]]) xs > | otherwise = cutBy z ( yss ++ [[x]]) xs This works as follows: MYExamples> cutBy 10 [ [] ] [3, 4, 2, 10, 7, 5, 1, 2] [[3,4,2], [10], [7], [5,1,2]] MYExamples> cutBy 10 [ [] ] [3, 4, 2, 10, 1, 7, 5, 1, 2] [[3,4,2], [10], [1,7], [5,1,2]] MYExamples> The beauty of Haskell is that because of lazy evaluation we could have infinite lists and the above function is a transformation of one stream into another -- e.g. we could model operations on a conveyor line. Of course the above will not work, because we are using last(). But this will work with streams: > cutBy :: (Num a, Ord a) => a -> [[a]] -> [a] -> [[a]] > cutBy z yss [] = yss > cutBy z (ys:yss) (x:xs) > | sum ys + x < z + 1 = cutBy z ((x : ys) : yss ) xs > | otherwise = cutBy z ([x] : ys : yss ) xs MYExamples> cutBy 10 [ [] ] [3, 4, 2, 10, 7, 5, 1, 2] [[2,1,5], [7], [10], [2,4,3]] MYExamples> cutBy 10 [ [] ] [3, 4, 2, 10, 1, 7, 5, 1, 2] [[2,1,5], [7,1], [10], [2,4,3]] MYExamples> ===== Cheers, Dimitre Novatchev. http://fxsl.sourceforge.net/ -- the home of FXSL "Benjamin Farrow" <lovinjess@xxxxxxxxxxx> wrote in message news:Law15-F58cDioalzvzy0000e86f@xxxxxxxxxxxxxx > Well perhaps I've found a solution...it appears to be working anyhow. Any > comments would be welcome. > > <xsl:stylesheet version="1.0" > xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> > > <xsl:key name="groupByTen" > match="ele" > use="ceiling(sum(preceding-sibling::ele/@sum|@sum) div 10)"/> > > <xsl:template match="/"> > <xsl:apply-templates select="node()|@*"/> > </xsl:template> > > <xsl:template match="ele"> > <xsl:variable name="sum" > select="sum(preceding-sibling::ele/@sum|@sum)"/> > <xsl:if test="generate-id(key('groupByTen',ceiling($sum div 10))[1]) = > generate-id(.) and > position() != 1"> > <br/> > </xsl:if> > <xsl:copy> > <xsl:apply-templates select="node()|@*"/> > </xsl:copy> > </xsl:template> > > <xsl:template match="node()|@*"> > <xsl:copy> > <xsl:apply-templates select="node()|@*"/> > </xsl:copy> > </xsl:template> > > </xsl:stylesheet> > > > > > > >From: "Benjamin Farrow" <lovinjess@xxxxxxxxxxx> > >Reply-To: xsl-list@xxxxxxxxxxxxxxxxxxxxxx > >To: xsl-list@xxxxxxxxxxxxxxxxxxxxxx > >Subject: [xsl] Grouping problem? > >Date: Tue, 22 Apr 2003 12:06:02 -0700 > > > >All, > > I don't know how to explain my problem in words very concisely, so I'll > >try with a simplified example. > > > >SourceXML: > ><root> > > <ele sum="3"/> > > <ele sum="4"/> > > <ele sum="2"/> > > <ele sum="10"/> > > <ele sum="7"/> > > <ele sum="5"/> > > <ele sum="1"/> > > <ele sum="2"/> > ></root> > > > >Desired Output: > ><root> > > <ele sum="3"/> > > <ele sum="4"/> > > <ele sum="2"/> > > <br/> <!-- next element makes total greater than 10 --> > > <ele sum="10"/> > > <br/> <!-- next element makes total greater than 20 --> > > <ele sum="7"/> > > <br/> <!-- next element makes total greater than 30 --> > > <ele sum="5"/> > > <ele sum="1"/> > > <ele sum="2"/> > ></root> > > > >I'm trying to break apart the ele element when the sum total of preceding > >siblings and self is greater than the increment of 10 by putting an element > >to denote the break. > > > >I've tried some crazy tests with mod and div and I've looked over the > >Muenchian grouping, but I still can't come up with a way to arbitrarily set > >the break points. I know there is a solution and I get close, but I just > >can't get around it. > > > >Here is my template (also have the standard identity template) with which > >I'm trying to get this working. I just can't figure out the if test for > >this though. > > > >XSL: > > <xsl:template match="ele"> > > <xsl:variable name="sum" > >select="sum(preceding-sibling::ele/@sum|@sum)"/> > > <xsl:if test="$sum > (floor($sum div 10) * 10)"> > > <br/> > > </xsl:if> > > <xsl:copy> > > <xsl:apply-templates select="node()|@*"/> > > </xsl:copy> > > </xsl:template> > > > >Thanks in advance, > > Benjamin > > > > > >_________________________________________________________________ > >MSN 8 with e-mail virus protection service: 2 months FREE* > >http://join.msn.com/?page=features/virus > > > > > >XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list > > > > > _________________________________________________________________ > Tired of spam? Get advanced junk mail protection with MSN 8. > http://join.msn.com/?page=features/junkmail > > > XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list > > XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list
Current Thread |
---|
|
<- Previous | Index | Next -> |
---|---|---|
RE: [xsl] Grouping problem?, Conal Tuohy | Thread | RE: [xsl] Re: Grouping problem?, Lars Huttar |
Re: [xsl] Selecting text bisected b, David Carlisle | Date | RE: [xsl] Grouping problem?, Conal Tuohy |
Month |