Hallo Julian,
Es soll genau ein einziges "Amount" unter "AllowanceOrCharge_DEEE" mit dem Gesamtwert geben.
XSLT-1.0-Variante mit xsl:call-template:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" standalone="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="AllowanceOrCharge_DEEE">
<xsl:copy>
<!--copy all other nodes-->
<xsl:apply-templates select="@* | node()"/>
<xsl:variable name="tx_anz" select="count(//Item[AllowanceOrCharge_Line[Code = 'TX']])"/>
<xsl:if test="$tx_anz >= 1">
<Amount>
<xsl:call-template name="calc_amount">
<xsl:with-param name="summe" select="0"/>
<xsl:with-param name="i" select="1"/>
<xsl:with-param name="max" select="$tx_anz"/>
</xsl:call-template>
</Amount>
</xsl:if>
</xsl:copy>
</xsl:template>
<!-- Identity-Template für die nicht explizit benannten Elemente -->
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
<xsl:template name="calc_amount">
<xsl:param name="summe"/>
<xsl:param name="i"/>
<xsl:param name="max"/>
<xsl:choose>
<xsl:when test="$i <= $max">
<xsl:variable name="produkt" select="//Item[AllowanceOrCharge_Line[Code = 'TX']][$i]/TotalQuantity * //Item[AllowanceOrCharge_Line[Code = 'TX']][$i]/AllowanceOrCharge_Line/Amount"/>
<xsl:call-template name="calc_amount">
<xsl:with-param name="summe" select="$summe + $produkt"/>
<xsl:with-param name="i" select="$i + 1"/>
<xsl:with-param name="max" select="$max"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="format-number($summe, '#.00')"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
Mit XSLT 2.0/3.0 und for-in-return gestaltet es sich deutlich kompakter. Die einzelnen aufzusummierenden Werte werden darüber innerhalb von sum(…) zunächst vorberechnet:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" standalone="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="AllowanceOrCharge_DEEE">
<xsl:copy>
<!--copy all other nodes-->
<xsl:apply-templates select="@* | node()"/>
<xsl:variable name="tx_anz" select="count(//Item[AllowanceOrCharge_Line[Code = 'TX']])"/>
<xsl:if test="$tx_anz >= 1">
<Amount>
<xsl:value-of select="format-number(sum(for $item in //Item[AllowanceOrCharge_Line[Code = 'TX']]
return $item/TotalQuantity * $item/AllowanceOrCharge_Line/Amount), '#.00')"/>
</Amount>
</xsl:if>
</xsl:copy>
</xsl:template>
<!-- Identity-Template für die nicht explizit benannten Elemente -->
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
Das Ergebnis ist jeweils:
[…]
<Totals>
<AllowanceOrCharge_DEEE>
<Code>TX</Code>
<Amount>166.40</Amount>
</AllowanceOrCharge_DEEE>
</Totals>
[…]
Grüße,
Thomas