Reputation: 31
I would like to calculate values depending on an attribute of the elements differently and later sum the calculated values.
The xml structure looks like this:
<elements>
<element type="type1">
<value>10</value>
<date>01.05.2012</date>
</element>
<element type="type2">
<value>20</value>
<date>02.03.2012</date>
</element>
<element type="type2">
<value>20</value>
<date>02.03.2012</date>
</element>
</elements>
I used xsd:alternatives
in the XSD to create the different "types" of elements.
The XSL looks like this:
<xsl:for-each select="/elements">
<xsl:sort select="date"/>
<xsl:choose>
<xsl:when test="type='type1'">
<xsl:value-of select="value*20"/>
<xsl:value-of select="date"/>
</xsl:when>
<xsl:when test="type='type1'">
<xsl:value-of select="value*10"/>
<xsl:value-of select="date"/>
</xsl:when>
</xsl:choose>
(Here should be a sum of all the values that have been calculated.)
</xsl:for-each>
I want to be able to show the value after it was calculated (with a factor depending on the "type" it is.), sort the different values by their dates and display the sum of all the calculated values.
I am sure there are better ways to do what I want to do and I am happy about any suggestions.
Upvotes: 2
Views: 5888
Reputation: 66781
Assuming that @type="type1" should be multiplied by 10 and
@type="type2"` should be multiplied by 20, the following stylesheet:
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text" indent="yes"/>
<xsl:template match="/">
<xsl:apply-templates select="elements/element">
<xsl:sort select="date" />
</xsl:apply-templates>
<xsl:value-of select="'
'"/>
<xsl:value-of select="sum(*/element[@type='type1']/value
[number()=number()]) * 10 +
sum(*/element[@type='type2']/value
[number()=number()]) * 20"/>
</xsl:template>
<xsl:template match="element[@type='type1']/value">
<xsl:value-of select=". * 10"/>
</xsl:template>
<xsl:template match="element[@type='type2']/value">
<xsl:value-of select=". * 20"/>
</xsl:template>
<!-- this matches any of the value elements who's values are not a number -->
<xsl:template match="element[@type]/value[number()!=number()]">
<xsl:text>0</xsl:text>
</xsl:template>
</xsl:stylesheet>
produces the following output:
100
01.05.2012
400
02.03.2012
400
02.03.2012
900
Upvotes: 1