Satiz
Satiz

Reputation: 17

How to product and sum the values of two different nodes of a different complex element using xslt?

My XML is

<root> <source> <item> <id>111</id> <qty>2</qty> </item> <item> <id>222</id> <qty>1</qty> </item> <item> <id>333</id> <qty>4</qty> </item> </source> <target> <record> <id>111</id> <price>1000</price> </record> <record> <id>333</id> <price>500</price> </record> </target> </root>

Now i need to match the id element of source/item and target/record if it matches i need to product the

source/item/qty * target/record/price

Once the product is done for all the matching case i should sum all product value and should get the result as

4000 i.e (sum(qty * price) of all matching elements.)

How to achieve this kindly help me on this , thanks in advance

Upvotes: 0

Views: 1306

Answers (2)

Joel M. Lamsen
Joel M. Lamsen

Reputation: 7173

I have modified this answer from Dimitre Novatchev to suit your requirement. The code is as follows:

<xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:strip-space elements="*"/>
    <xsl:output indent="yes" omit-xml-declaration="yes"/>

    <xsl:key name="target" match="record" use="id" />

    <xsl:template match="/">
        <xsl:call-template name="sumProducts">
            <!-- get only sources with respective equivalent targets -->
            <xsl:with-param name="pList" select="*/*/item[key('target', id)]"/>
            <!-- a list of target records -->
            <xsl:with-param name="pList2" select="*/*/record"/>
        </xsl:call-template>
    </xsl:template>

    <xsl:template name="sumProducts">
        <xsl:param name="pList"/>
        <xsl:param name="pList2"/>
        <xsl:param name="pAccum" select="0"/>

        <xsl:choose>
            <xsl:when test="$pList">
                <xsl:variable name="vHead" select="$pList[1]"/>
                <xsl:variable name="vHead2" select="$pList2"/>

                <xsl:call-template name="sumProducts">
                    <xsl:with-param name="pList" select="$pList[position() > 1]"/>
                    <xsl:with-param name="pList2" select="$pList2"/>
                    <xsl:with-param name="pAccum"
                        select="$pAccum + $vHead/qty * $vHead2[id = $vHead/id]/price"/>
                </xsl:call-template>
            </xsl:when>
            <xsl:otherwise>
                <xsl:value-of select="$pAccum"/>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:template>
</xsl:stylesheet>

Upvotes: 0

michael.hor257k
michael.hor257k

Reputation: 117043

In XSLT 2.0, you can do:

<xsl:key name="target" match="record" use="id" />

<xsl:template match="/root">
    <result>
        <xsl:value-of select="sum(source/item[key('target', id)]/(qty * key('target', id)/price))"/>
    </result>
</xsl:template>

Upvotes: 0

Related Questions