Adem İlhan
Adem İlhan

Reputation: 1500

Multiply nodes value using XSLT

I need to get a value which is coming from two different nodes in the same XML file. For instance, my xml:

 <asset>
      <curr_wanted>EUR</curr_wanted>
      <curr>USD</curr>
      <value>50</value>
    </asset>

    <exchangeRates>
      <USD>
        <USD>1</USD>
        <EUR>0.73</EUR>
      </USD>
    </exchangeRates>

and I want to get equivalent of 50 Dollars in Euro.

I tried :

<xsl:value-of select="(Asset/value * /exchangeRates[node() = curr]/curr_wanted)"/>

But it didn't work. Also I have to use XSLT 1.0. How can I get that value in Euro?

Upvotes: 2

Views: 6760

Answers (1)

Jirka Š.
Jirka Š.

Reputation: 3428

I did not test it very much but for input like

<?xml version="1.0" encoding="UTF-8"?>
<root>
    <asset>
      <curr_wanted>EUR</curr_wanted>
      <curr>USD</curr>
      <value>50</value>
    </asset>
    <asset>
      <curr_wanted>EUR</curr_wanted>
      <curr>USD</curr>
      <value>25</value>
    </asset>    
    <exchangeRates>
      <USD>
        <USD>1</USD>
        <EUR>0.73</EUR>
      </USD>
    </exchangeRates>
</root>

something like following could work

for $asset in /root/asset, $rate in /root/exchangeRates 
    return $asset/value*$rate/*[name() = $asset/curr]/*[name() = $asset/curr_wanted] 

But it will work only in xpath 2.0 and it also depends on the whole input xml (like if there might exist more asset elements, more exchangeRates elements, etc.).

Edit: In xslt 1.0 you could use xsl:variable to store some information and prevent them from context changes during xpath evaluation. Look for example at following template

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fo="http://www.w3.org/1999/XSL/Format">
    <xsl:output method="text" />

    <!-- Store "exchangeRates" in a global variable-->
    <xsl:variable name="rates" select="/root/exchangeRates" />  

    <xsl:template match="/root">
        <xsl:apply-templates select="asset" />
    </xsl:template>

    <xsl:template match="asset">
        <!-- Store necessary values into local variables -->
        <xsl:variable name="currentValue" select="value" />
        <xsl:variable name="currentCurrency" select="curr" />
        <xsl:variable name="wantedCurrency" select="curr_wanted" />
        <xsl:variable name="rate" select="$rates/*[name() = $currentCurrency]/*[name() = $wantedCurrency]" />

        <!-- Some text to visualize results -->
        <xsl:value-of select="$currentValue" />
        <xsl:text> </xsl:text>
        <xsl:value-of select="$currentCurrency" />
        <xsl:text> = </xsl:text>

        <!-- using variable to prevent context changes during xpath evaluation -->
        <xsl:value-of select="$currentValue * $rate" />

        <!-- Some text to visualize results -->
        <xsl:text> </xsl:text>
        <xsl:value-of select="$wantedCurrency" />

        <xsl:text>&#10;</xsl:text>
    </xsl:template>

</xsl:stylesheet>

which produces following output for input xml above.

50 USD = 36.5 EUR
25 USD = 18.25 EUR

Upvotes: 4

Related Questions