2014-05-25 4 views
0

J'ai essayé d'obtenir le montant total dépensé par un utilisateur sur des produits mais sans succès. Compte tenu de l'exemple XML suivant, le montant total dépensé par le client serait 21,00 mais je reçois 10,50 (cela se produit uniquement si le client achète plusieurs fois le même produit, s'il achète différents produits le montant retour est prévu le)Avoir des problèmes de somme, xslt 1.0

exemple XML:

<root> 
      <sale id="1"> 
       <date>2014-01-01</date> 
       <client>1</client> 
      </sale> 

      <sale id="2"> 
       <date>2014-01-02</date> 
       <client>1</client> 
      </sale> 

      <sale_details saleID="1"> 
       <product id="1"/> 
      </sale_details> 

      <sale_details saleID="2"> 
       <product id="1"/> 
      </sale_details> 

      <product_details productID="1"> 
       <name>product x</name> 
       <price>10.50</price> 
      </product_details> 

      <product_details productID="2"> 
       <name>product x</name> 
       <price>5.26</price> 
      </product_details> 

      <client_detail clientID="1"> 
       <name>client 1</name> 
      </client_detail> 

      <client_detail clientID="2"> 
       <name>client 2</name> 
      </client_detail> 
    </root> 

échantillon XSLT:

<xsl:template name="sum-spent-amount"> 
    <xsl:param name="clientID"/> 
    <xsl:value-of select="sum(//gv:product_details[@productID=//gv:sale_details[@saleID=//gv:sale[gv:client=$clientID]/@id]/gv:product/@id]/gv:price)"/> 
</xsl:template> 

Merci à l'avance!

Répondre

0

Bien sûr, vous obtenez un résultat de 10,5: vous additionnez les uniques instances des produits vendus. Vous devez additionner les prix des ventes réelles. Voici une façon de le faire:

XSLT 1,0

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
xmlns:exsl="http://exslt.org/common" 
exclude-result-prefixes="exsl"> 
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/> 

<xsl:param name="clientID" select="1"/> 

<xsl:key name="sale-by-clientID" match="sale" use="client" /> 
<xsl:key name="sale_detail-by-saleID" match="sale_details" use="@saleID" /> 
<xsl:key name="product-by-id" match="product_details" use="@productID" /> 

<xsl:template match="/"> 
    <xsl:variable name="mySaleIDs" select="key('sale-by-clientID', $clientID)/@id" /> 
    <xsl:variable name="prices"> 
     <xsl:for-each select="key('sale_detail-by-saleID', $mySaleIDs)"> 
      <price><xsl:value-of select="key('product-by-id', product/@id)/price"/></price> 
     </xsl:for-each> 
    </xsl:variable> 

    <sum><xsl:value-of select="sum(exsl:node-set($prices)/price)"/></sum> 
</xsl:template> 

</xsl:stylesheet> 

Lorsque cela est appliqué à votre entrée, le résultat est:

<?xml version="1.0" encoding="UTF-8"?> 
<sum>21</sum> 
+0

Hey @ michael.hor257k, je vous remercie pour votre réponse rapide. Serait-ce possible sans exsl? – vitor

+0

@vitor Peut-être, mais pourquoi? Je ne connais aucun processeur XSLT 1.0 qui ne supporte pas exsl: node-set(). –

+0

J'ai lu à ce sujet mais c'est pour un projet d'université, je dois utiliser ce qui a été enseigné, j'ai essayé mais je ne peux pas obtenir la bonne solution. – vitor

0

Je suis arrivé à cette solution en utilisant le modèle récursif :

Le modèle:

<xsl:template name="sum"> 

    <xsl:param name="nodes"/> 
    <xsl:param name="total" select="0"/> 

    <xsl:variable name="current" select="$nodes[1]" /> 
    <xsl:choose> 
     <xsl:when test="$current">    
      <xsl:variable name="product" select="//gv:product_details[@productID=$current/gv:product/@id]"/> 
      <xsl:call-template name="sum"> 

       <xsl:with-param name="nodes" select="$nodes[position() &gt; 1]"/> 
       <xsl:with-param name="total" select="$total + $product/gv:price"/> 

      </xsl:call-template> 
     </xsl:when> 
     <xsl:otherwise><xsl:value-of select="$total"/></xsl:otherwise> 
    </xsl:choose> 

</xsl:template> 

Utilisation du modèle ici:

<xsl:variable name="clientID" select="1"/> 
<xsl:call-template name="sum"> 
    <xsl:with-param name="nodes" select="//gv:sale_details[@saleID=//gv:sale[gv:client=clientID]/@id]" /> 
</xsl:call-template>