Here is a somewhat detailed but general approach:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="xml" indent="yes"/> <xsl:param name="taxType" select="11" /> <xsl:template match="transactions"> <result> <xsl:variable name="allValues" select="transaction/@*[substring(local-name(), 5, 5) = 'Type'] [. = $taxType]" /> <xsl:call-template name="SumValues"> <xsl:with-param name="items" select="$allValues" /> </xsl:call-template> </result> </xsl:template> <xsl:template name="SumValues"> <xsl:param name="items" /> <xsl:param name="total" select="0" /> <xsl:choose> <xsl:when test="not($items)"> <xsl:value-of select="$total" /> </xsl:when> <xsl:otherwise> <xsl:variable name="currentItem" select="$items[1]" /> <xsl:variable name="currentValue"> <xsl:apply-templates select="$currentItem" mode="getMatchingValue" /> </xsl:variable> <xsl:call-template name="SumValues"> <xsl:with-param name="items" select="$items[position() > 1]" /> <xsl:with-param name="total" select="$total + $currentValue" /> </xsl:call-template> </xsl:otherwise> </xsl:choose> </xsl:template> <xsl:template match="@*" mode="getMatchingValue"> <xsl:variable name="typeCodeLetter" select="substring(local-name(), 4, 1)" /> <xsl:variable name="valueAttributeName" select="concat('Tax', $typeCodeLetter, 'Value')" /> <xsl:variable name="matchingValueAttribute" select="../@*[local-name() = $valueAttributeName]" /> <xsl:value-of select="$matchingValueAttribute * boolean($matchingValueAttribute)"/> </xsl:template> </xsl:stylesheet>
This should be able to handle any number of Tax*Type (as long as the * character is the only character), and the desired type can be passed as a parameter.
source share