Asdemuertes
Asdemuertes

Reputation: 323

xsl , sum of nodes which satisfy a certain condition

i would like to know how to get sum of nodes only when they satisfy a condition,having the xml:

<segma>
    <conservacio>
        <cons estat="A">Excel·lent conservació</cons>
        <cons estat="B">Bona conservació</cons>
        <cons estat="C">Regular conservació</cons>
        <cons estat="D">Mala conservació</cons>
    </conservacio>

    <categories>
        <categoria cat="1">Mobiliari</categoria>
        <categoria cat="2">Alimentació</categoria>
        <categoria cat="3">Roba</categoria>
    </categories>

    <clients>
        <registre dni="111">Marti</registre>
        <registre dni="222">Jana</registre>
        <registre dni="333">Edu</registre>
        <registre dni="444">Santi</registre>
        <registre dni="555">Mia</registre>
        <registre dni="666">Pau M</registre>        
    </clients>

    <productes>
        <prod id="1" cons="A" cat="1">
            <nom>Cuna</nom>
            <preu_nou>70</preu_nou>
            <preu>30</preu>
            <ofertes>
                <oferta client="111" />
                <oferta client="333" />
            </ofertes>
            <venta client="111" />
        </prod>

        <prod id="2" cons="B" cat="2">
            <nom>Baby cook</nom>
            <preu_nou>120</preu_nou>
            <preu>60</preu>
            <ofertes>
                <oferta client="111" />
                <oferta client="333" />
                <oferta client="444" />
                <oferta client="555" />

                </ofertes>
            <venta client="555" />
        </prod>         

        <prod id="3" cons="A" cat="1">
            <nom>Mama pata</nom>
            <preu_nou>70</preu_nou>
            <preu>5</preu>
            <ofertes>
                <oferta client="444" />
                <oferta client="555" />
            </ofertes>
            <venta client="444" />
        </prod>     

        <prod id="4" cons="B" cat="3">
            <nom>Conjunt xandall</nom>
            <preu_nou>40</preu_nou>
            <preu>15</preu>
            <ofertes>
                <oferta client="222" />
                <oferta client="555" />
            </ofertes>
            <venta client="222" />
        </prod> 

        <prod id="5" cons="C" cat="3">
            <nom>Pack 3 texans</nom>
            <preu_nou>70</preu_nou>
            <preu>25</preu>
            <ofertes>
                <oferta client="333" />
                <oferta client="444" />
                <oferta client="555" />
            </ofertes>
            <venta client="333" />
        </prod> 

        <prod id="6" cons="A" cat="2">
            <nom>Saca leches</nom>
            <preu_nou>130</preu_nou>
            <preu>70</preu>
            <ofertes>
                <oferta client="111" />
                <oferta client="222" />
                <oferta client="555" />
            </ofertes>
            <venta client="111" />
        </prod>     

        <prod id="7" cons="C" cat="2">
            <nom>Llet continuació</nom>
            <preu_nou>11</preu_nou>
            <preu>3</preu>
            <ofertes>
            </ofertes>
        </prod>             

    </productes>
</segma>

I want to make a list of which products has a client bought(prod/venta/@client), and the sum of prices("preu") of the products:

Having an xsl like :

<h2>Ex 4</h2>
      <table border="1">
    <xsl:for-each select="//registre">
    <xsl:variable name="dni" select="@dni"/>

    <tr>
     <td> <xsl:value-of select="."/></td>

     <xsl:for-each select="//prod">

     <xsl:if test="venta/@client=$dni">
     <td><xsl:value-of select="nom"/></td>

     </xsl:if>
     </xsl:for-each>

I would like to get an output like :

client1 prod1 prod2 sum_of_price_prod1+prod2

client2 prod4 prod6 prod 7 sum_of_price_of(prod4+prod6+prod7)

Ex: Maria Baby Cook Texans 744.35

Sorry for the bad english.

Upvotes: 0

Views: 87

Answers (1)

Tim C
Tim C

Reputation: 70648

You can define a variable to hold all the prod elements current...

<xsl:variable name="prod" select="//prod[venta/@client=$dni]" />

Then you can list select the prod elements like so...

<xsl:for-each select="$prod">

And to get the total sum you can do this...

 <xsl:value-of select="sum($prod/preu)" />

Try this XSLT

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="html" doctype-public="XSLT-compat" omit-xml-declaration="yes" encoding="UTF-8" indent="yes" />

<xsl:template match="/">
    <h2>Ex 4</h2>
        <table border="1">
            <xsl:for-each select="//registre">
                <xsl:variable name="dni" select="@dni"/>
                <xsl:variable name="prod" select="//prod[venta/@client=$dni]" />
                <tr>
                    <td><xsl:value-of select="."/></td>
                    <td>
                    <xsl:for-each select="$prod">
                           <xsl:value-of select="nom"/><br />
                    </xsl:for-each>
                    </td>
                    <td>
                        <xsl:value-of select="sum($prod/preu)" />
                    </td>
                </tr>
            </xsl:for-each>
        </table>
    </xsl:template>
</xsl:stylesheet>

Alternatively, you could use an xsl:key to look up the prod elements

<xsl:key name="prod" match="prod" use="venta/@client" />

Try this XSLT too

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="html" doctype-public="XSLT-compat" omit-xml-declaration="yes" encoding="UTF-8" indent="yes" />

<xsl:key name="prod" match="prod" use="venta/@client" />

<xsl:template match="/">
    <h2>Ex 4</h2>
        <table border="1">
            <xsl:for-each select="//registre">
                <tr>
                    <td><xsl:value-of select="."/></td>
                    <td>
                    <xsl:for-each select="key('prod', @dni)">
                           <xsl:value-of select="nom"/><br />
                    </xsl:for-each>
                    </td>
                    <td>
                        <xsl:value-of select="sum(key('prod', @dni)/preu)" />
                    </td>
                </tr>
            </xsl:for-each>
        </table>
    </xsl:template>
</xsl:stylesheet>

Upvotes: 1

Related Questions