Группировка XSLT с SUM не работает, если первый путь не имеет соответствующего элемента

При суммировании с группировкой и соответствием узел не существует в первом элементе этой группы, тогда результат будет пустым.

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>

Результат

Стейси--

Ожидаемый результат

Стейси-- 20

Примечание. В тот момент, когда мы меняем узел DeductionAdjustmentsNotToInclude на DeductionAdjustments (означает, что первый элемент этой группы имеет соответствующий узел), результат отображается правильно (т.е. - Стейси-- 75).


person Manish    schedule 14.12.2016    source источник


Ответы (1)


Сначала в вашем XML вам нужно исправить опечатку "DeductionAdjustmentss". Сделав это, это работает:

    <?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>
person Drew Rhoades    schedule 14.12.2016