2013-02-13 128 views
0

源XML檢查超過2個值量:總和在記錄

<?xml version="1.0" encoding="UTF-8"?> 
<Emp> 
    <EmpDetail> 
     <ProjectDetails> 
      <Code>Project</Code> 
      <ProjectReference> 
       <Reference> 
        <RefCode>PROJ1</RefCode> 
       </Reference> 
      </ProjectReference> 
     </ProjectDetails> 
     <ProjectDetails> 
      <Code>Element</Code> 
      <ProjectReference> 
       <Reference> 
        <RefCode>ELEM1</RefCode> 
       </Reference> 
      </ProjectReference> 
     </ProjectDetails> 
     <Period> 
      <PeriodNo>1</PeriodNo> 
     </Period> 
     <AmountDetails> 
      <Currency>EUR</Currency> 
      <Amount> 
       <Value>100.00</Value> 
      </Amount> 
     </AmountDetails> 
    </EmpDetail> 
    <EmpDetail> 
     <ProjectDetails> 
      <Code>Project</Code> 
      <ProjectReference> 
       <Reference> 
        <RefCode>PROJ1</RefCode> 
       </Reference> 
      </ProjectReference> 
     </ProjectDetails> 
     <ProjectDetails> 
      <Code>Element</Code> 
      <ProjectReference> 
       <Reference> 
        <RefCode>ELEM1</RefCode> 
       </Reference> 
      </ProjectReference> 
     </ProjectDetails> 
     <Period> 
      <PeriodNo>1</PeriodNo> 
     </Period> 
     <AmountDetails> 
      <Currency>EUR</Currency> 
      <Amount> 
       <Value>5000</Value> 
      </Amount> 
     </AmountDetails> 
    </EmpDetail> 
    <EmpDetail> 
     <ProjectDetails> 
      <Code>Project</Code> 
      <ProjectReference> 
       <Reference> 
        <RefCode>PROJ2</RefCode> 
       </Reference> 
      </ProjectReference> 
     </ProjectDetails> 
     <ProjectDetails> 
      <Code>Element</Code> 
      <ProjectReference> 
       <Reference> 
        <RefCode>ELEM2</RefCode> 
       </Reference> 
      </ProjectReference> 
     </ProjectDetails> 
     <Period> 
      <PeriodNo>2</PeriodNo> 
     </Period> 
     <AmountDetails> 
      <Currency>EUR</Currency> 
      <Amount> 
       <Value>200.00</Value> 
      </Amount> 
     </AmountDetails> 
    </EmpDetail> 
    <EmpDetail> 
     <ProjectDetails> 
      <Code>Project</Code> 
      <ProjectReference> 
       <Reference> 
        <RefCode>PROJ2</RefCode> 
       </Reference> 
      </ProjectReference> 
     </ProjectDetails> 
     <ProjectDetails> 
      <Code>Element</Code> 
      <ProjectReference> 
       <Reference> 
        <RefCode>ELEM2</RefCode> 
       </Reference> 
      </ProjectReference> 
     </ProjectDetails> 
     <Period> 
      <PeriodNo>3</PeriodNo> 
     </Period> 
     <AmountDetails> 
      <Currency>EUR</Currency> 
      <Amount> 
       <Value>500</Value> 
      </Amount> 
     </AmountDetails> 
    </EmpDetail> 
</Emp> 

目標XML:

<?xml version="1.0" encoding="UTF-8"?> 
<Emp> 
    <EmpDetail> 
     <ProjectDetails> 
      <Code>Project</Code> 
      <ProjectReference> 
       <Reference> 
        <RefCode>PROJ1</RefCode> 
       </Reference> 
      </ProjectReference> 
     </ProjectDetails> 
     <ProjectDetails> 
      <Code>Element</Code> 
      <ProjectReference> 
       <Reference> 
        <RefCode>ELEM1</RefCode> 
       </Reference> 
      </ProjectReference> 
     </ProjectDetails> 
     <Period> 
      <PeriodNo>1</PeriodNo> 
     </Period> 
     <AmountDetails> 
      <Currency>EUR</Currency> 
      <Amount> 
       <Value>5100.00</Value> 
      </Amount> 
     </AmountDetails> 
    </EmpDetail> 
    <EmpDetail> 
     <ProjectDetails> 
      <Code>Project</Code> 
      <ProjectReference> 
       <Reference> 
        <RefCode>PROJ2</RefCode> 
       </Reference> 
      </ProjectReference> 
     </ProjectDetails> 
     <ProjectDetails> 
      <Code>Element</Code> 
      <ProjectReference> 
       <Reference> 
        <RefCode>ELEM2</RefCode> 
       </Reference> 
      </ProjectReference> 
     </ProjectDetails> 
     <Period> 
      <PeriodNo>2</PeriodNo> 
     </Period> 
     <AmountDetails> 
      <Currency>EUR</Currency> 
      <Amount> 
       <Value>200.00</Value> 
      </Amount> 
     </AmountDetails> 
    </EmpDetail> 
    <EmpDetail> 
     <ProjectDetails> 
      <Code>Project</Code> 
      <ProjectReference> 
       <Reference> 
        <RefCode>PROJ2</RefCode> 
       </Reference> 
      </ProjectReference> 
     </ProjectDetails> 
     <ProjectDetails> 
      <Code>Element</Code> 
      <ProjectReference> 
       <Reference> 
        <RefCode>ELEM2</RefCode> 
       </Reference> 
      </ProjectReference> 
     </ProjectDetails> 
     <Period> 
      <PeriodNo>3</PeriodNo> 
     </Period> 
     <AmountDetails> 
      <Currency>EUR</Currency> 
      <Amount> 
       <Value>500</Value> 
      </Amount> 
     </AmountDetails> 
    </EmpDetail> 
</Emp> 

查詢:如果PeriodNo,項目的RefCode和元素的RefCode是相同的話,我必須總和金額值並且應該只產生一條記錄。在我的源文件中,前兩行項目的periodno,項目的refcode和元素的refcode是相同的,所以想要在輸出中只得到一個記錄,並且金額值應該是(100 + 5000)= 5100。

I有想法,如果我必須檢查一個值,並做的lineitem的總和,但在這種情況下,我必須檢查每個記錄中的3個值,我總結它。你能告訴我,如何使用xslt繼續使用它。我有XSLT 1.0版本。

回答

0

我不知道你現在是否已經找到解決方案,但是因爲沒有解決方案發布在這裏,所以我發佈了基於Muenchian Grouping的Mine。

我試圖用註釋來解釋代碼,希望它有幫助。

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

    <xsl:output method="xml" indent="yes"/> 

    <!-- Copy by default attributes, elements and text -->  
    <xsl:template match="*|@*"> 
     <xsl:copy><xsl:apply-templates select="node()|@*" /></xsl:copy> 
    </xsl:template> 


    <!-- Key which is going to allow us to identify each EmpDetail by the 
     following id (which is a string): ProjectRefCode-ElementRefCode-PeriodNo 

     Using the key function we are going to be able to select the set of 
     EmpDetail nodes which have the described structure. So elements with 
     the same id (i.e. same ProjectRefCode, ElementRefCode and PeriodNo) 
     are going to be matched using: key('detail-key', $id), where $id holds 
     the id to be matched. --> 
    <xsl:key name="detail-key" 
      match="Emp/EmpDetail" 
      use="concat(ProjectDetails[Code = 'Project']/ProjectReference/Reference/RefCode, '-', 
         ProjectDetails[Code = 'Element']/ProjectReference/Reference/RefCode, '-', 
         Period/PeriodNo)" /> 

    <xsl:template match="Emp"> 

     <!-- Copy the current node and process its children EmpDetail elements --> 
     <xsl:copy> 
      <!-- We use key('detail-key', $id)[1] where the $id is the concat 
       expression to select one element per group, i.e. we iterate 
       over a set of unique EmpDetail elements --> 
      <xsl:apply-templates select="EmpDetail[generate-id(.) = generate-id(key('detail-key', 
               concat(ProjectDetails[Code = 'Project']/ProjectReference/Reference/RefCode, '-', 
               ProjectDetails[Code = 'Element']/ProjectReference/Reference/RefCode, '-', 
               Period/PeriodNo))[1])]" /> 
     </xsl:copy> 
    </xsl:template> 

    <!-- When the Value element is found, we perform the sum of all the Value elements 
     which are contained in the group matched by the id described above--> 
    <xsl:template match="Value"> 

     <!-- Cache parent node to avoid repeated operations --> 
     <xsl:variable name="current-detail" 
         select="../../.." /> 

     <!-- Generate the id for the current EmpDetail element as described 
      above --> 
     <xsl:variable name="detail-id" 
         select="concat($current-detail/ProjectDetails[Code = 'Project']/ProjectReference/Reference/RefCode, '-', 
            $current-detail/ProjectDetails[Code = 'Element']/ProjectReference/Reference/RefCode, '-', 
            $current-detail/Period/PeriodNo)" /> 

     <!-- Wrap the sum with the Value element --> 
     <xsl:copy> 
      <!-- We use the key function to fetch all the EmpDetail elements with the 
      same id as the current one and sum them --> 
      <xsl:value-of select="sum(key('detail-key', $detail-id)/AmountDetails/Amount/Value)" /> 
     </xsl:copy> 

    </xsl:template>  
</xsl:stylesheet>