This is the mail archive of the xsl-list@mulberrytech.com mailing list .


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

AW: RPN calculator


Thank you Jeni, and David and Oleg...! I love this list!
Regarding Jeni's answer, actually I do not understand the purpose of using a
mode (besides learning something new for me...). 
And I tried it, but it doesn't work, I think because it enters the multiply
or sum templates without the "calculate" mode.

Regarding David's answer, extending my question:
What about doing a real RPN calculator, that can accept things like:
<calculate>1 3 + 2 *</calculate>?
Should I use F


-----Ursprüngliche Nachricht-----
Von: Jeni Tennison [mailto:jeni@jenitennison.com]
Gesendet am: Donnerstag, 2. Mai 2002 13:32
An: Costantino.Sertorio@evk.admin.ch
Cc: xsl-list@lists.mulberrytech.com
Betreff: Re: [xsl] RPN calculator

Hi Costantino,

> I'm trying to do a simple calculator with XSL.
> This means that I would like to transform something like (but I can change
> the source format, this is only an example):
> <multiply>
>         <arg1>2</arg1>
>         <arg2>3</arg2>
> </multiply>
> This should yeld 6, and it's easy.
> But I would also like to do:
> <multiply>
>         <arg1>
>                 <sum>
>                         <arg1>1</arg1>
>                         <arg2>2</arg2>
>                 </sum>
>         </arg1>
>         <arg2>3</arg2>
> </multiply>
> ...and so on, recursively. As with an RPN calculator.
> This should yeld (1+2)*3=6.
>
> Can anybody point me in the right direction? How can I do this?

Set up a mode called 'calculate'; applying templates to a a node in
this mode will give you the result of the calculation. If you apply
templates to a text node in calculate mode, then you want to return
the value of the text node (with spaces normalized -- this eliminates
insignificant whitespace):

<xsl:template match="text()" mode="calculate">
  <xsl:value-of select="normalize-space()" />
</xsl:template>

If you apply templates to a multiply element in calculate mode, then
you want to get the results of apply templates in calculate mode to
the child nodes of its arg1 and arg2 elements, and multiply the
results together:

<xsl:template match="multiply" mode="calculate">
  <xsl:variable name="arg1">
    <xsl:apply-templates select="arg1/node()" mode="calculate" />
  </xsl:variable>
  <xsl:variable name="arg2">
    <xsl:apply-templates select="arg2/node()" mode="calculate" />
  </xsl:variable>
  <xsl:value-of select="$arg1 * $arg2" />
</xsl:template>

Similarly for the sum element:

<xsl:template match="multiply" mode="calculate">
  <xsl:variable name="arg1">
    <xsl:apply-templates select="arg1/node()" mode="calculate" />
  </xsl:variable>
  <xsl:variable name="arg2">
    <xsl:apply-templates select="arg2/node()" mode="calculate" />
  </xsl:variable>
  <xsl:value-of select="$arg1 + $arg2" />
</xsl:template>

In your first example above, the child nodes of the arg1 and arg2
elements are both text nodes so you get the value of the text node. In
the second example, the child node of arg1 is a sum element, so you
get the result of applying templates to the sum element, which in turn
is the result of apply templates to the text node children of its own
arg1 and arg2 children and summing them.

Cheers,

Jeni

---
Jeni Tennison
http://www.jenitennison.com/

 XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]