user2032464
user2032464

Reputation: 27

xslt sort and sum of nodes basing on the sort ..?

 <fo:block start-indent="5mm">  
    <xsl:for-each select="//policyResult[not(AgentNumber=preceding-sibling::policyResult/AgentNumber)]" >    
    <xsl:variable name="agentNum"><xsl:value-of select="AgentNumber"></xsl:value-of>  
    </xsl:variable>                 
    <xsl:for-each select="//policyResult[AgentNumber=$agentNum]">    
<xsl:sort select="agentnumber"/>
<xsl:sort select="policynumber"/>
    <fo:table border-style="" width="100%" border-spacing="4">                          
    <fo:table-body>    
    <fo:table-row border-before-style="solid">   
    <fo:table-cell>   
    <fo:block>
           <fo:inline>Pol Number</fo:inline><xsl:value-of select="PolicyNumber"/>    
    </fo:block>    
    </fo:table-cell>        
    </fo:table-body>    
    </fo:table> 

i written some code like this to filter the nodes which are repeated. here my problem is i have to sort this in ascending order.the xml looks like this

    <policyResult xmlns="" xmlns:ns2="http://ws.faithlife.com/resonant">
                                   <producttype>risk</producttype>                            <PolicyNumber>003050669</PolicyNumber>    
                    <AgentNumber>005262</AgentNumber>
                    <AnnualPremium>12000.0</AnnualPremium>                  
    </policyResult>
    <policyResult xmlns="" xmlns:ns2="http://ws.faithlife.com/resonant">
<producttype>wealth</producttype>                   
<PolicyNumber>003050669</PolicyNumber>
                    <AgentNumber>005282</AgentNumber>
                    <AnnualPremium>12000.0</AnnualPremium>                  
    </policyResult>

    <policyResult xmlns="" xmlns:ns2="http://ws.faithlife.com/resonant">
<producttype>risk</producttype>
                    <PolicyNumber>003050670</PolicyNumber>
                    <AgentNumber>005262</AgentNumber>
                    <AnnualPremium>12000.0</AnnualPremium>      

    </policyResult>
    <policyResult xmlns="" xmlns:ns2="http://ws.faithlife.com/resonant">
<producttype>wealth</producttype>
                    <PolicyNumber>003050671</PolicyNumber>
                    <AgentNumber>005263</AgentNumber>
                    <AnnualPremium>12000.0</AnnualPremium>                      
    </policyResult>
    <policyResult xmlns="" xmlns:ns2="http://ws.faithlife.com/resonant">
<producttype>wealth</producttype>
                    <PolicyNumber>003050668</PolicyNumber>
                    <AgentNumber>005265</AgentNumber>
                    <AnnualPremium>12000.0</AnnualPremium>                  
    </policyResult>
    <policyResult xmlns="" xmlns:ns2="http://ws.faithlife.com/resonant">
<producttype>wealth</producttype>
                    <PolicyNumber>003050668</PolicyNumber>
                    <AgentNumber>005265</AgentNumber>
                    <AnnualPremium>12000.0</AnnualPremium>                  
    </policyResult>

what i have to do is filter the AgentNumber ,AnnualPremium in ascending order.and need sum the Annualpremium of each agent and sum of all Annualpremium.

the out put should be like this. if the agent number repeats we have to show it only once in ascending order

product type risk

agent number 005266

policynumber 003050669 anuual premium 12000

policynumber 003050671 anuual premium 12000

total annual premium --sum of premium of this agent i.e 24000

agent number 005267

policynumber 0001234 anuual premium 11000

policynumber 0001235 anuual premium 11000 total annual premium --sum of premium of this agent i.e 22000

product type wealth

agent number 005266

policynumber 003050669 anuual premium 12000

policynumber 003050671 anuual premium 12000

total annual premium --sum of premium of this agent i.e 24000

agent number 005267

policynumber 0001234 anuual premium 11000

policynumber 0001235 anuual premium 11000 total annual premium --sum of premium of this agent i.e 22000

at the end we need to display overall annual premium of all the agents

total premiums---24000+22000=46000

please help me out..thanks in advance

need this kind of output..

Upvotes: 0

Views: 180

Answers (1)

G. Ken Holman
G. Ken Holman

Reputation: 4403

This answer should be approached as a grouping problem, not as a path problem.

I noted that your "expected results" do not correspond to your inputs, so I modified your inputs to match your expected results.

Consider the following solution. Given you have tagged this as XSLT 1.0, you need to use the Muenchen method of grouping.

t:\ftemp>type policies.xml
<?xml version="1.0" encoding="UTF-8"?>
<policies>
<policyResult xmlns="" xmlns:ns2="http://ws.faithlife.com/resonant">
                <PolicyNumber>003050669</PolicyNumber>
                <AgentNumber>005266</AgentNumber>
                <AnnualPremium>12000.0</AnnualPremium>
</policyResult>
<policyResult xmlns="" xmlns:ns2="http://ws.faithlife.com/resonant">
                <PolicyNumber>0001235</PolicyNumber>
                <AgentNumber>005267</AgentNumber>
                <AnnualPremium>11000.0</AnnualPremium>
</policyResult>
<policyResult xmlns="" xmlns:ns2="http://ws.faithlife.com/resonant">
                <PolicyNumber>0001234</PolicyNumber>
                <AgentNumber>005267</AgentNumber>
                <AnnualPremium>11000.0</AnnualPremium>
</policyResult>
<policyResult xmlns="" xmlns:ns2="http://ws.faithlife.com/resonant">
                <PolicyNumber>003050671</PolicyNumber>
                <AgentNumber>005266</AgentNumber>
                <AnnualPremium>12000.0</AnnualPremium>
</policyResult>
</policies>
t:\ftemp>xslt policies.xml policies.xsl

Agent Number: 005266
Policy Number: 003050669 Premium: 12000.0
Policy Number: 003050671 Premium: 12000.0
Total for agent: 24000
Agent Number: 005267
Policy Number: 0001234 Premium: 11000.0
Policy Number: 0001235 Premium: 11000.0
Total for agent: 22000
Total for all: 46000
t:\ftemp>type policies.xsl
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  version="1.0">

<xsl:output method="text"/>

<!--establish the key for the grouping-->
<xsl:key name="agent" match="policyResult" use="AgentNumber"/>

<xsl:template match="policies">
  <!--perform the grouping per agent-->
  <xsl:for-each
    select="policyResult[generate-id(.)=
                         generate-id(key('agent',AgentNumber)[1])]">
    <!--sort the groups by AgentNumber-->
    <xsl:sort select="AgentNumber"/>
Agent Number: <xsl:value-of select="AgentNumber"/>
    <!--revisit policies for agent-->
    <xsl:for-each select="key('agent',AgentNumber)">
      <!--sort groups by policy number-->
      <xsl:sort select="PolicyNumber"/>
Policy Number: <xsl:value-of select="PolicyNumber"/> Premium: <xsl:value-of
                             select="AnnualPremium"/>
    </xsl:for-each>
Total for agent: <xsl:value-of
                      select="sum(key('agent',AgentNumber)/AnnualPremium)"/>
  </xsl:for-each>
Total for all: <xsl:value-of select="sum(policyResult/AnnualPremium)"/>
</xsl:template>

</xsl:stylesheet>
t:\ftemp>

I'll leave the XSL-FO to you.

Upvotes: 1

Related Questions