Reputation: 3
I need help with something, I need transform this file, but i have this condition: when the QTY > 0 and QTY < 1, I should replace for 1 and finally sum all values
I have this XML:
<?xml version="1.0" encoding="UTF-8" ?>
<DellistDocument>
<DELLIST>
<QTY>3.50</QTY>
</DELLIST>
<DELLIST>
<QTY>0.002</QTY>
</DELLIST>
<DELLIST>
<QTY>0.80</QTY>
</DELLIST>
</DellistDocument>
I need loop for every QTY and change the values if is necessary in the transform map, I need to do a sum like this:
<QTY>3.50</QTY> ----> value = 3.50
<QTY>0.002</QTY> ----> value = 1
<QTY>0.80</QTY> ----> value = 1
Total Sum = 5.50
I try with this, but really I'm stuck about how to do this :
<xsl:variable name="QTYItem">
<xsl:for-each select="$Dellist">
<xsl:variable name="QTYCountItemValue" select="number(normalize-space(QTY/text()))" />
<xsl:variable name="QTYItemValidateValue">
<xsl:choose>
<xsl:when test="$QTYCountItemValue > 0 and $QTYCountItemValue < 1">
<xsl:value-of select="number(1)" />
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="number($QTYCountItemValue)" />
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:value-of select="sum($QTYItemValidateValue)" />
</xsl:for-each>
</xsl:variable>
<xsl:value-of select="$QTYItem" />
The result of this is : 3.5011 , This is putting the loop values, but I need to sum all, how can I do this? I expect as a result 5.50
I'm working in XSLT 3.0
Thank you so much.
Upvotes: 0
Views: 1016
Reputation: 117165
There is no need to loop in order to sum values. Here you could do simply:
XSLT 2.0
<xsl:template match="/DellistDocument">
<output>
<xsl:value-of select="sum(DELLIST/(if (number(QTY) gt 0 and number(QTY) lt 1) then 1 else number(QTY)))"/>
</output>
</xsl:template>
Demo: https://xsltfiddle.liberty-development.net/pNmCzsX/1
Upvotes: 1
Reputation: 2714
Here's a way this could be done. There might be easier ways...
Not sure what your required output is, but you can modify the output format if required.
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:my="http://www.my.com"
exclude-result-prefixes="xs my"
version="3.0">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="DellistDocument">
<xsl:copy>
<xsl:apply-templates/>
<TOTAL><xsl:value-of select="my:total(DELLIST[1],0)"/></TOTAL>
</xsl:copy>
</xsl:template>
<xsl:template match="QTY[number(.)>0 and number(.)<1]">
<xsl:copy>
<xsl:value-of select="1"/>
</xsl:copy>
</xsl:template>
<!-- Recursive function to round the numbers and add them -->
<xsl:function name="my:total" as="xs:double">
<xsl:param name="currDELLIST"/>
<xsl:param name="total"/>
<xsl:variable name="currQTY" select="($currDELLIST/QTY)[1]"/>
<xsl:variable name="round" select="if($currQTY>0 and $currQTY<1) then 1 else $currQTY"/>
<xsl:sequence select="if($currDELLIST/following-sibling::DELLIST)
then my:total($currDELLIST/following-sibling::DELLIST, $round+$total)
else $round+$total"/>
</xsl:function>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
See it working here : https://xsltfiddle.liberty-development.net/jxDjimT
Upvotes: 0