分享

XSLT : Cummulative Sum (Conditional)

 shineboy1 2015-10-28

I need to do a conditional sum using XSLT. The sum of 'Oty' for each 'SKU' should be calculated only for providers listed within the 'Provider' node. In the provided example, the Qty for providerCode 4 should be skipped as its not in the 'Providers' list. I'm restricted to using XSLT 1.0.

I would appreciate any help. Thanks!

Here is the sample XML.

<?xml version="1.0" encoding="UTF-8"?>
<Root>
    <Providers>
        <ProviderCode>1</ProviderCode>
        <ProviderCode>2</ProviderCode>
        <ProviderCode>3</ProviderCode>        
    </Providers>
    <SKU>
        <SKU>XYZ</SKU>
        <Description>XYZ Description</Description>
        <Provider>
            <ProviderCode>1</ProviderCode>
            <Qty>100</Qty>
        </Provider>
        <Provider>
            <ProviderCode>2</ProviderCode>
            <Qty>67</Qty>
        </Provider>
        <Provider>
            <ProviderCode>3</ProviderCode>
            <Qty>74</Qty>
        </Provider>
        <Provider>
            <ProviderCode>4</ProviderCode>
            <Qty>62</Qty>
        </Provider>    
    </SKU>
    <SKU>
        <SKU>ABC</SKU>
        <Description>ABC Description</Description>
        <Provider>
            <ProviderCode>1</ProviderCode>
            <Qty>20</Qty>
        </Provider>
        <Provider>
            <ProviderCode>2</ProviderCode>
            <Qty>77</Qty>
        </Provider>
        <Provider>
            <ProviderCode>3</ProviderCode>
            <Qty>42</Qty>
        </Provider>    
        <Provider>
            <ProviderCode>4</ProviderCode>
            <Qty>631</Qty>
        </Provider>    
    </SKU>    
</Root>

Here is the required output.

<?xml version="1.0" encoding="UTF-8"?>
<Root>
    <SKU>
        <SKU>XYZ</SKU>
        <Qty>241</Qty>
    </SKU>
    <SKU>
        <SKU>ABC</SKU>
        <Qty>139</Qty>
    </SKU>    
</Root>
asked Jul 5 '13 at 17:38
PManual
52
    
And the code xslt?. would help. – A. M. Mérida Jul 5 '13 at 17:47

1 Answer

up vote 2 down vote accepted

You can simply use sum on the nodes you want, either by comparing sum(Provider[ProviderCode = //Providers/ProviderCode]/Qty) or by using a key:

<xsl:stylesheet
  version="1.0"
  xmlns:xsl="http://www./1999/XSL/Transform">

<xsl:output indent="yes"/>

<xsl:key name="prov" match="Providers/ProviderCode" use="."/>

<xsl:template match="Root">
  <xsl:copy>
    <xsl:apply-templates select="SKU"/>
  </xsl:copy>
</xsl:template>

<xsl:template match="Root/SKU">
  <xsl:copy>
    <xsl:copy-of select="SKU"/>
    <Qty><xsl:value-of select="sum(Provider[key('prov', ProviderCode)]/Qty)"/></Qty>
  </xsl:copy>
</xsl:template>

</xsl:stylesheet>
answered Jul 5 '13 at 17:56
Martin Honnen
63.4k52644
    
+1 good answer. One small typo in your opening paragraph: that XPath should be sum(Provider[ProviderCode = //Providers/ProviderCode]/Qty) . – ABach Jul 5 '13 at 18:12
    
Great!! With the latest change sum(Provider[ProviderCode = //Providers/ProviderCode]/Qty), the sum value is correct. Thanks again!! – PManual Jul 5 '13 at 20:05
    
@ABach, thanks for the correction, now fixed in the answer. – Martin Honnen Jul 6 '13 at 8:49
1  
@user2554529, the inline path sample was incorrect, but the complete code sample with the key solution has been correct in the first version of the answer and is more efficient anyway. – Martin Honnen Jul 6 '13 at 8:51
    
@MartinHonnen, I've posted another question at </questions/17531066/…; that uses your answer as the 'base'. It would be great if you provide your comments in it. Thanks!. P.S: I couldn't post it as comment here as the code sample exceeds the number of chars. – PManual Jul 8 '13 at 16:02

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多