Subject: Re: [xsl] For-each loop or recursion From: Oleg Konovalov <olegkon@xxxxxxxxx> Date: Mon, 16 May 2005 19:11:46 -0400 |
Aron, Thank you very much. It was very helpful. My solution to get was similar, but without Count. Thanks again, Oleg. On 5/16/05, Aron Bock <aronbock@xxxxxxxxxxx> wrote: > Oleg, > > > >Existing code is very complex - big Cocoon project > > Which is why I, among other people, have been asking for a "representative" > example. It doesn't have to be your actual XML. Just make up something > that's representative. Making up a representative sample is possible, as > you'll see at the end of this note. > > >(and I started using XSLT 2 weeks ago, but have lots of experience in > >Java/C/C++), so I tried to keep concentrated on what I am doing: > > Nobody's questioning your competency with those languages. But since you > mention it, it seems you're giving into the thinking that if you're > proficient at something, it's an admission of, uh, who knows what, to start > from basics in another field. You're saying, "tell me how this is done, and > I'm smart enough/nice enough/whatever enough to apply it myself", whereas > sampes and descriptions you've provided thus far show only that you're > bringing to bear imperative solutions on declarative problems. Trust me on > this--provide a sample, and you'll get all the specific help you need. > > >At this point I am interested in how to implement algorithms in XSLT: > >a) find out first non-zero on either rebate1 and rebate2 > >b) find out first occurrence of max number in either rebate1 or rebate2 > > This was already answered succintly by a prior respondent, who suggested you > use a loop and pick out the first/last element. > > > >So back to my questions: > >1) How do I get a position of last occurrence of min ? > > Many ways, 2 of which may be: > --locate the node and count its preceding siblings > --count number of min and adjust > > >1a) Can I scan using for-each loop from the end of the sequence > >to the beginning ? > > yes, see <xsl:sort> and its attributes > > >2) OK, lets try to get a position of the first occurrence when var2 = max > >node. > >What would be a correct ? > > > ><xsl:for-each select=mystruct/myarray1[1]/myvar> > > <xsl:if select="rebate1=*[last()]"> > > <xsl:value-of select="position()"> > > </xsl:if> > ></xsl:for-each> > > > >3) Expanding 2 for the rebate2 (var3) for the values from another > >(parallel) branch, > >would that work ? > > > ><xsl:for-each select=mystruct/myarray1[1]/myvar> > > <xsl:if select="rebate1=*[last()] and > > ../../../myarray2[1]/myvar/rebate2=*[last()]"> > > <xsl:value-of select="position()"> > > </xsl:if> > ></xsl:for-each> > > > >I think, that second *[last()] is wrong, > >I have to get a max of the rebate2 (second sequence) > >before that for-each loop. > > > >3a) Can I calculate max of rebate2 like: > ><xsl:variable name="max2" > >select="mystruct/myarray2[1]/myvar/rebate2[position()=last()]"> > >Is that the right way of assigning *[last()] to a variable ? > > These need more context to respond to with any value. As a prior respondent > said, showing just the XSL is of little use--without the corresponding XML > it's more often than not futile to comment on its semantics. > > Now, using your description below, *I'll* make up XML, and write simple, if > verbose, XSL to get your results: > > > >column to be displayed [first non-zero on either rebate1 and rebate2] > >and the last one [first occurrence of max number in either rebate1 or > >rebate2] > > > > 1 2 3 4 5 6 7 8 9 10 11 12 > >13 (sales volume) > >rebate1(%) 0 0 1 2 3 4 5 6 7 8 8 8 8 > >rebate2(%) 0 1 2 3 4 5 6 7 9 10 11 11 11 > > > >Need it be dynamically trimmed to display: > > > > 2 3 4 5 6 7 8 9 10 "11 or more" > >rebate1(%) 0 1 2 3 4 5 6 7 8 8 > >rebate2(%) 1 2 3 4 5 6 7 9 10 11 > > > >So if it makes it any easier, we can call it > >mystruct/myarray1[1]/myvar/rebate1 and > >mystruct/myarray2[1]/myvar/rebate2 > > This XML: > > <mystruct> > <myarray1> > <myvar><rebate1>0</rebate1></myvar> > <myvar><rebate1>0</rebate1></myvar> > <myvar><rebate1>1</rebate1></myvar> > <myvar><rebate1>2</rebate1></myvar> > <myvar><rebate1>3</rebate1></myvar> > <myvar><rebate1>4</rebate1></myvar> > <myvar><rebate1>5</rebate1></myvar> > <myvar><rebate1>6</rebate1></myvar> > <myvar><rebate1>7</rebate1></myvar> > <myvar><rebate1>8</rebate1></myvar> > <myvar><rebate1>8</rebate1></myvar> > <myvar><rebate1>8</rebate1></myvar> > </myarray1> > <myarray2> > <myvar><rebate2>0</rebate2></myvar> > <myvar><rebate2>1</rebate2></myvar> > <myvar><rebate2>2</rebate2></myvar> > <myvar><rebate2>3</rebate2></myvar> > <myvar><rebate2>4</rebate2></myvar> > <myvar><rebate2>5</rebate2></myvar> > <myvar><rebate2>6</rebate2></myvar> > <myvar><rebate2>7</rebate2></myvar> > <myvar><rebate2>9</rebate2></myvar> > <myvar><rebate2>10</rebate2></myvar> > <myvar><rebate2>11</rebate2></myvar> > <myvar><rebate2>11</rebate2></myvar> > <myvar><rebate2>11</rebate2></myvar> > </myarray2> > </mystruct> > > With this XSL: > > (This could be shortened, but I'm unwilling to put in any more time w/ > guessed-at data) > > <?xml version="1.0" encoding="iso8859-1"?> > <xsl:stylesheet version="1.0" > xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> > <xsl:output method="text"/> > > <xsl:template match="/"> > <xsl:call-template name="raw-data"/> > <xsl:text>
</xsl:text> > <xsl:call-template name="trimmed-data"/> > </xsl:template> > > <xsl:template name="raw-data"> > <xsl:text>raw data (sorted)
</xsl:text> > <xsl:text>rebate1 </xsl:text> > <xsl:apply-templates select="mystruct/myarray1/myvar/rebate1"> > <xsl:sort data-type="number" select="."/> > </xsl:apply-templates> > <xsl:text>
</xsl:text> > > <xsl:text>rebate2 </xsl:text> > <xsl:apply-templates select="mystruct/myarray2/myvar/rebate2"> > <xsl:sort data-type="number" select="."/> > </xsl:apply-templates> > <xsl:text>
</xsl:text> > </xsl:template> > > <xsl:template name="trimmed-data"> > <!-- pos of first non-zero rebate1 --> > <xsl:variable name="pr1" > select="count(mystruct/myarray1/myvar/rebate1[. <= 0]) + 1"/> > > <!-- pos of first non-zero rebate2 --> > <xsl:variable name="pr2" > select="count(mystruct/myarray2/myvar/rebate2[. <= 0]) + 1"/> > > <!-- pos of first non-zero rebate* --> > <xsl:variable name="pr"> > <xsl:choose> > <xsl:when test="$pr1 <= $pr2"> > <xsl:value-of select="$pr1"/> > </xsl:when> > <xsl:otherwise> > <xsl:value-of select="$pr2"/> > </xsl:otherwise> > </xsl:choose> > </xsl:variable> > > <!-- max rebate1 --> > <xsl:variable name="mr1"> > <xsl:for-each select="mystruct/myarray1/myvar/rebate1"> > <xsl:sort data-type="number" select="."/> > <xsl:if test="position() = last()"> > <xsl:value-of select="."/> > </xsl:if> > </xsl:for-each> > </xsl:variable> > > <!-- pos first max rebate1 --> > <xsl:variable name="pmr1" > select="count(mystruct/myarray1/myvar/rebate1[. < $mr1]) + 1"/> > > <!-- max rebate2 --> > <xsl:variable name="mr2"> > <xsl:for-each select="mystruct/myarray2/myvar/rebate2"> > <xsl:sort data-type="number" select="."/> > <xsl:if test="position() = last()"> > <xsl:value-of select="."/> > </xsl:if> > </xsl:for-each> > </xsl:variable> > > <!-- pos first max rebate2 --> > <xsl:variable name="pmr2" > select="count(mystruct/myarray2/myvar/rebate2[. < $mr2]) + 1"/> > > <!-- pos of greater max rebate* --> > <xsl:variable name="pmr"> > <xsl:choose> > <xsl:when test="$pmr1 >= $pmr2"> > <xsl:value-of select="$pmr1"/> > </xsl:when> > <xsl:otherwise> > <xsl:value-of select="$pmr2"/> > </xsl:otherwise> > </xsl:choose> > </xsl:variable> > > <xsl:text>trimmed data
</xsl:text> > <xsl:text>rebate1 </xsl:text> > <xsl:for-each select="mystruct/myarray1/myvar/rebate1"> > <xsl:if test="position() >= $pr and position() <= $pmr"> > <xsl:apply-templates select="."/> > </xsl:if> > </xsl:for-each> > <xsl:text>
</xsl:text> > > <xsl:text>rebate2 </xsl:text> > <xsl:for-each select="mystruct/myarray2/myvar/rebate2"> > <xsl:if test="position() >= $pr and position() <= $pmr"> > <xsl:apply-templates select="."/> > </xsl:if> > </xsl:for-each> > <xsl:text>
</xsl:text> > </xsl:template> > > <xsl:template match="rebate1"> > <xsl:value-of select="."/> > <xsl:text> </xsl:text> > </xsl:template> > > <xsl:template match="rebate2"> > <xsl:value-of select="."/> > <xsl:text> </xsl:text> > </xsl:template> > > </xsl:stylesheet> > > Produces: > > raw data (sorted) > rebate1 0 0 1 2 3 4 5 6 7 8 8 8 > rebate2 0 1 2 3 4 5 6 7 9 10 11 11 11 > > trimmed data > rebate1 0 1 2 3 4 5 6 7 8 8 > rebate2 1 2 3 4 5 6 7 9 10 11 > > Regards, > > --A > > _________________________________________________________________ > Express yourself instantly with MSN Messenger! Download today - it's FREE! > http://messenger.msn.click-url.com/go/onm00200471ave/direct/01/
Current Thread |
---|
|
<- Previous | Index | Next -> |
---|---|---|
Re: [xsl] For-each loop or recursio, Aron Bock | Thread | Re: [xsl] For-each loop or recursio, omprakash . v |
Re: [xsl] How to prevent xmlns attr, Michael . Giroux | Date | [xsl] word (not string) wrap, jpk |
Month |