0

源代码:

<?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、Project 的 RefCode 和 Element 的 RefCode 相同,那么我必须对金额值求和,并且应该只生成一条记录。在我的源文件中,前两个 line item 的 periodno、project 的 refcode 和 element 的 refcode 是相同的,所以想在输出中只获取一条记录,并且金额值应该是 (100+5000) = 5100。

我知道我是否必须检查一个值并计算 lineitem 的总和,但在这种情况下,我必须检查每条记录中的 3 个值并且我已经对其求和。您能否告诉我,如何使用 xslt 进行操作。我有 XSLT 1.0 版本。

4

1 回答 1

0

我不知道你是否已经找到了解决方案,但由于这里没有发布解决方案,所以我发布了我的解决方案,该解决方案位于 Muenchian Grouping。

我尝试使用注释来解释代码,希望对您有所帮助。

<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>
于 2013-02-17T15:58:42.937 回答