Reputation: 1535
Here is a snippet of some XSLT code.
It is outputting the results concatenated instead of summed. For example it will find the following matches: 100
and 200
and will output 12002400
. Which is 100 * 12
and 200 * 12
concatenated. I need the output in XMLField1
to be 3600
.
Can someone point me in the right direction and help explain what we are doing wrong? I'm not an XSLT expert.
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="Root">
<XMLField1>
<xsl:apply-templates
select="Row[contains(BenefitType, 'MyBenefit')]" />
</XMLField1>
<xsl:template match="Row[contains(BenefitType, 'MyBenefit')]">
<xsl:value-of select="sum(BenefitList/Premium) * 12" />
</xsl:template>
I am looking for an XSLT 1.0 compliant solution.
Upvotes: 0
Views: 726
Reputation: 23637
Your second template is performing calculations separately, but your aren't using that for anything. You don't need the second template if you just want the sum of all Premium
nodes in rows that contain MyBenefit
:
<xsl:template match="Root">
<XMLField1>
<xsl:value-of
select="sum(Row[contains(BenefitType, 'MyBenefit')]/BenefitList/Premium) * 12" />
</XMLField1>
</xsl:template>
This would produce:
<XMLField1>3600</XMLField1>
UPDATE:
You didn't post your source XML. I'm assuming it has a structure that resembles this:
<Root>
<Row>
<BenefitType>MyBenefit</BenefitType>
<BenefitList>
<Premium>100</Premium>
</BenefitList>
</Row>
<Row>
<BenefitType>MyBenefit, OtherBenefit</BenefitType>
<BenefitList>
<Premium>100</Premium>
</BenefitList>
</Row>
<Row>
<BenefitType>OtherBenefit</BenefitType>
<BenefitList>
<Premium>1000</Premium>
</BenefitList>
</Row>
<Row>
<BenefitType>OtherBenefit</BenefitType>
<BenefitList>
<Premium>1000</Premium>
</BenefitList>
</Row>
<Row>
<BenefitType>MyBenefitSpecial</BenefitType>
<BenefitList>
<Premium>100</Premium>
</BenefitList>
</Row>
</Root>
Since you are using contains()
it's important to be aware that it will match strings that contain MyBenefit
(including MyBenefit, OtherBenefit
, MyBenefitSpecial
)
Here is an online working example: http://xsltransform.net/bFukv8t/1
If you created a second template because you wanted separate results for each row, then you just have to add something in the template. A tag perhaps:
<xsl:template match="Row[contains(BenefitType, 'MyBenefit')]">
<subtotal>
<xsl:value-of select="sum(BenefitList/Premium) * 12" />
</subtotal>
</xsl:template>
which would produce for the sample input I provided above:
<XMLField1>
<subtotal>1200</subtotal>
<subtotal>1200</subtotal>
<subtotal>1200</subtotal>
</XMLField1>
You can have both the sum and this result if you change your other template:
<xsl:template match="Root">
<XMLField1>
<total><xsl:value-of
select="sum(Row[contains(BenefitType, 'MyBenefit')]/BenefitList/Premium) * 12" />
</total>
<xsl:apply-templates select="Row[contains(BenefitType, 'MyBenefit')]"/>
</XMLField1>
</xsl:template>
Now you will get:
<XMLField1>
<total>3600</total>
<subtotal>1200</subtotal>
<subtotal>1200</subtotal>
<subtotal>1200</subtotal>
</XMLField1>
Hopefully you can apply these examples to your real case scenario and obtain the results you are expecting.
Upvotes: 2