XSLT Grouping with SUM not working when first path doesnot have the relevant item

82 views Asked by At

When doing sum with grouping and matching node doesnot exists in first element of this group then result is blank.

XML

<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="EmployeeDetailStylesheet.xsl" ?>
<PayDetailsExportResult xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
   <PayDetailExport>
      <PayrollBatches>
         <PayrollBatch>

            <PayBatchEmployees>
               <PayrollBatchEmployee>
                  <FirstName>Stacey</FirstName>                  
                  <NationalId>999999999</NationalId>                  
                  <PayrollBatchDetails>
                     <PayrollBatchDetail>
                        <DeductionAdjustmentsNotToInclude>
                           <DeductionAdjustment>                              
                              <TakenAmount>55.00</TakenAmount>                              
                              <DeductionType>401(k)</DeductionType>                              
                           </DeductionAdjustment>
                        </DeductionAdjustmentsNotToInclude>
                     </PayrollBatchDetail>
                  </PayrollBatchDetails>
                </PayrollBatchEmployee>
            </PayBatchEmployees>

         </PayrollBatch>

         <PayrollBatch>    

            <PayBatchEmployees>
               <PayrollBatchEmployee>
                  <FirstName>Stacey</FirstName>
                  <NationalId>111111111</NationalId>
                  <PayrollBatchDetails>
                     <PayrollBatchDetail>                        
                        <DeductionAdjustmentss>
                           <DeductionAdjustment>
                              <TakenAmount>70.00</TakenAmount>
                              <DeductionType>401(k) - Catch up</DeductionType>
                           </DeductionAdjustment>
                        </DeductionAdjustmentss>
                     </PayrollBatchDetail>
                     <PayrollBatchDetail>
                        <DeductionAdjustments>
                           <DeductionAdjustment>
                              <TakenAmount>20.00</TakenAmount>
                              <DeductionType>401(k)</DeductionType>
                           </DeductionAdjustment>
                        </DeductionAdjustments>
                     </PayrollBatchDetail>
                  </PayrollBatchDetails>
               </PayrollBatchEmployee>
            </PayBatchEmployees>
         </PayrollBatch>

      </PayrollBatches>
   </PayDetailExport>
</PayDetailsExportResult>

XSLT

<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:msxsl="urn:schemas-microsoft-com:xslt" xmlns:pdi="http://www.profdata.com" 
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

    <!-- strip-space removes whitespace nodes such as tabs and newlines that occur  between elements.-->
    <xsl:strip-space elements="*"/>

    <!-- Set output method to indicate a text file (not XML) -->        
    <xsl:output method="text" encoding="utf-8" indent="yes"/>

    <xsl:key name="payrollBatchEmpGroup" match="PayrollBatchEmployee" use="NationalId" />   
    <xsl:key name="deductionAdjustmentGroup" match="DeductionAdjustments/DeductionAdjustment" use="concat(../../../../NationalId, '+', DeductionType)" />

    <xsl:template match="PayDetailsExportResult">               
        <!-- Output the CSV data row -->
        <xsl:for-each select="PayDetailExport/PayrollBatches/PayrollBatch">

            <xsl:for-each select="PayBatchEmployees/PayrollBatchEmployee[count(. | key('payrollBatchEmpGroup', NationalId)[1]) = 1]">

                <xsl:variable name="ssn" select="NationalId" />
                <xsl:value-of select="FirstName"/>
                <text>--</text> 

                <xsl:for-each select="PayrollBatchDetails/PayrollBatchDetail[DeductionAdjustments]">                    

                    <xsl:for-each select="DeductionAdjustments/DeductionAdjustment[DeductionType='401(k)'][count(. | key('deductionAdjustmentGroup', concat($ssn, '+', DeductionType))[1]) = 1]">
                        <xsl:value-of select="sum(key('deductionAdjustmentGroup', concat($ssn , '+' , DeductionType))/TakenAmount)" />                      
                    </xsl:for-each>

                </xsl:for-each>

                <!--End of row-->           
                <xsl:text>&#xA;</xsl:text>                      
            </xsl:for-each>

        </xsl:for-each>
    </xsl:template>
</xsl:stylesheet>

Result

Stacey--

Expected Result

Stacey-- 20

Note :- The moment we change node DeductionAdjustmentsNotToInclude to DeductionAdjustments (means first element of this group has matching node) result displaying correctly (i.e. - Stacey-- 75).

1

There are 1 answers

0
Drew Rhoades On

First in your XML, you need to correct the "DeductionAdjustmentss" typo. Having done that, this works:

    <?xml version="1.0"?>
    <xsl:stylesheet version="1.0" xmlns:msxsl="urn:schemas-microsoft-com:xslt" xmlns:pdi="http://www.profdata.com" 
                    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

        <!-- strip-space removes whitespace nodes such as tabs and newlines that occur  between elements.-->
        <xsl:strip-space elements="*"/>

        <!-- Set output method to indicate a text file (not XML) -->        
        <xsl:output method="text" encoding="utf-8" indent="yes"/>

        <xsl:key name="payrollBatchEmpGroup" match="PayrollBatchEmployee" use="NationalId" />   
        <xsl:key name="deductionAdjustmentGroup" match="DeductionAdjustments/DeductionAdjustment" use="concat(../../../../NationalId, '+', DeductionType)" />

        <xsl:template match="PayDetailsExportResult">               
            <!-- Output the CSV data row -->
            <xsl:for-each select="PayDetailExport/PayrollBatches/PayrollBatch/PayBatchEmployees/PayrollBatchEmployee/PayrollBatchDetails/PayrollBatchDetail/DeductionAdjustments/DeductionAdjustment
                [DeductionType='401(k)' and count(. | key('deductionAdjustmentGroup', concat(../../../../NationalId, '+', DeductionType))[1]) = 1]">
                <xsl:value-of select="key('payrollBatchEmpGroup', ../../../../NationalId)/FirstName"/>
                <text>--</text>
                <xsl:value-of select="sum(key('deductionAdjustmentGroup', concat(../../../../NationalId, '+' , DeductionType))/TakenAmount)" />         
                <!--End of row-->           
                <xsl:text>&#xA;</xsl:text>                      
            </xsl:for-each>
        </xsl:template>
    </xsl:stylesheet>