Subject: Re: [xsl] For-each loop or recursion From: "Aron Bock" <aronbock@xxxxxxxxxxx> Date: Mon, 16 May 2005 18:17:46 +0000 |
Existing code is very complex - big Cocoon project
(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:
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
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 ?
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 ?
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
<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>
<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>
<!-- 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>
<!-- 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 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>
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
Current Thread |
---|
|
<- Previous | Index | Next -> |
---|---|---|
Re: [xsl] For-each loop or recursio, Oleg Konovalov | Thread | Re: [xsl] For-each loop or recursio, Oleg Konovalov |
Re: [xsl] XSLT 2.0 Is Way Cool, Eliot Kimber | Date | RE: [xsl] making a number from a de, Wendell Piez |
Month |