Re: [xsl] For-each loop or recursion

Subject: Re: [xsl] For-each loop or recursion
From: Oleg Konovalov <olegkon@xxxxxxxxx>
Date: Sun, 15 May 2005 23:48:05 -0400
David,

Answering your questions:

> > I have the following data (leaves in parallel branches):
> > mystruct/myarray1[i]/myvar/var2 and
> > mystruct/myarray2[i]/myvar/var3
>
> It isn't clear what you mean by the myarray[i] construct, that is a
> legal XPath expression that selects all elements called myarray that
> have a child element called i. I suspect that isn't what you want,
> I could make some guesses as to what you do mean but in any case that
> presumably is not your data, but rather a sketch of part of your
> stylesheet accessing the data. You need to say what your input looks like.

To be very honest, I am not totally sure myself about myarray1[i].
As I said, that is not my code (author is long gone), and I am new to XSLT.
I am just trying to make enhancements. That is how that node is
accessed everywhere.
In fact, it is mostly myarray1[1] and myarray2[1],
what you can call "parallel branches".

>
> > I need to implement the find the first occurence of :
> > <xsl:if test="position() != last() and
> >   number(var2) = number(var2[position()+1]) and
> >   number(var3) = number(var3[position()+1])">
> >       <value-of select="position()">
> > </xsl:if>
>
> Again I'm struggling to guess what you mean here. You need to describe
> the transformation that you want to do, either in english or by posting a
> small (six line) example input and stating what result you want to get
> from that input.
>
> the above is syntactically legal Xpath but
> var2[position()+1] is short for var2[position()=position()+1]
> so selects the set of var2 elements for which the position is equal to
> one more than the position so this is the empty set.
> applying number() to that always produced NotaNumber. NaN is never = to
> any other value (including itself) so the two = tests in the expression
> will never be true so the xsl:if will never return anything.

I need to compare current and next values of the node var2 [and var3]
and find the first occurrence when var2[position()] = var2[next, i.e.
position()+1]
Are you saying that is impossible to do in XSLT ?
If not, how should I do it ?


> > 2) Will I be able to get a node from the parallel branch in for-each loop
?
> > Something like:
> > <xsl:for-each mystruct/myarray1[i]/myvar>
> >   <xsl:if test=" ...and number(../../myarray2[i]/myvar/var3) =
> > number((../../myarray2[i]/myvar/var3)[position()+1]) and...">
> >     <value-of select="position()">
> >   </xsl:if>
> > </xsl:for-each>)
> > I know it looks awful  :-(
> As in the other cases this is syntactically legal but probably not what
> you want to do, but it doesn't give us any indication of what you _do_
> want to do.

I want from inside for-each loop mystruct/myarray1[i]/myvar
[or does it require recursion?]
compare the values is the parallel branch,
of parallel "current" node ../../myarray2[i]/myvar/var3 and its "next node".
Again, where:
mystruct/myarray1[i]/myvar/var2 and
mystruct/myarray2[i]/myvar/var3


> > 3) Is there a way to somehow start the for-each loop
> > from position other than 1 ?
>
> for-each isn't looping over some counter like a Fortran DO loop, it is
> iterating over a set of nodes, position() reports the order in which the
> nodes are being processed so obviously it alwyas starts with
> position()=1 This position() value has no relationship with any position
> of the node in the document tree: you can select any nodes (and using
> xsl:sort) process them in any order.
> for example if your current node has 10 child elements called x and you
> go
> <xsl:for-each select="x[position()&gt;3]">
> then the first node processed will be the 4th x child, but position()
> will be equal to 1 in that first iteration.

Not sure about Fortran, I am from Java world.

Is there an easy way to find out the max value of the node (child elements)
without sorting it ?
The sequence of nodes I am dealing with is supposed to be in increasing
order,
but might repeat the particular node. So I am in fact looking for the
1st occurrence
of max  value in 2 branches to say "6 (max) or more" and not to
display the rest.
FYI: displaying the table with value rebates for particular product,
so now it looks like:

                    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

Since rebate1 and rebate2 are coming from totally different
database tables [and calculated based on totally different criteria],
they are put in different XML structures, but happen to be on the
same nesting level.

Do you understand what I am doing now ?

What is the easiest way to achieve it, via for-loop or recursion ?


Thank you.
Oleg.

Current Thread