首页 > 解决方案 > 按相同值对节点进行分组并求和

问题描述

我正在尝试对它们进行分组并对它们pi:PD进行求和,但是,我的每个组代码不起作用。这是我的 XML。pi:Datepi:Codepi:Amt

<pi:PEE xmlns:pi="urn:com.workday/picof">
<pi:PG>
    <pi:HDR>
        <pi:Version>23</pi:Version>
    </pi:HDR>
    <pi:EMP>
        <pi:EAD>
            <pi:Code>1D</pi:Code>
            <pi:Date>2017-05-08</pi:Date>
            <pi:Amt>20.72</pi:Amt>
        </pi:EAD>
        <pi:PD>
            <pi:Code>SDF</pi:Code>
            <pi:Date>2021-02-19</pi:Date>
            <pi:Amt>40</pi:Amt>
        </pi:PD>
        <pi:PD>
            <pi:Code>SDB</pi:Code>
            <pi:Date>2021-02-26</pi:Date>
            <pi:Amt>2</pi:Amt>
        </pi:PD>
        <pi:PD>
            <pi:Code>SDB</pi:Code>
            <pi:Date>2021-02-26</pi:Date>
            <pi:Amt>30</pi:Amt>
        </pi:PD>
        <pi:AI>
            <pi:EDI>2020-05-01</pi:EDI>
        </pi:AI>
    </pi:EMP>
    <pi:EMP>
        ...
    </pi:EMP>
</pi:PG></pi:PEE>

这是我的 XSLT。我想知道什么是缺失或错误的,我可以用什么来纠正。谢谢!

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:pi="urn:com.workday/picof" version="2.0">

<xsl:output indent="yes" method="xml" />
<xsl:strip-space elements="*" />

<xsl:template match="@* | node()">
<xsl:copy>
    <xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>

<xsl:template match="pi:EMP">
    <xsl:if test="pi:EAD or pi:PD">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:if>
</xsl:template>

<xsl:template match="pi:AI"/>

<xsl:template match="pi:PD">
    <xsl:for-each-group select="." group-by="concat(pi:Date,pi:Code)">
        <pi:PD>
        <xsl:for-each select="current-group()">
            <pi:Code><xsl:value-of select="pi:Code"/></pi:Code>
            <pi:Date><xsl:value-of select="pi:Date"/></pi:Date>
            <pi:Amt><xsl:value-of select="sum(current-group()/pi:Amt)"/></pi:Amt>
        </xsl:for-each>
        </pi:PD>
    </xsl:for-each-group>
</xsl:template>
</xsl:stylesheet>

标签: xmlxsltxslt-2.0

解决方案


只需转到父级别并运行您的分组需求,您可以在其中组合pi:EMPpi:PD模板,如下所示。使用xsl:if删除的空模板处理pi:AI. 最后,内部xsl:for-each>是没有必要的。使用空模板和身份转换模板在下面运行。

<xsl:template match="pi:EMP">
   <xsl:copy> 
      <xsl:copy-of select="pi:EAD"/>
      <xsl:for-each-group select="pi:PD" group-by="concat(pi:Date,pi:Code)"> 
         <xsl:copy> 
            <xsl:copy-of select="pi:Code|pi:Date"/>
            <pi:Amt><xsl:value-of select="sum(current-group()/pi:Amt)"/></pi:Amt> 
         </xsl:copy>
     </xsl:for-each-group> 
   </xsl:copy>
</xsl:template> 

输出

<pi:PEE xmlns:pi="urn:com.workday/picof">
   <pi:PG>
      <pi:HDR>
         <pi:Version>23</pi:Version>
      </pi:HDR>
      <pi:EMP>
         <pi:EAD> 
            <pi:Code>1D</pi:Code> 
            <pi:Date>2017-05-08</pi:Date> 
            <pi:Amt>20.72</pi:Amt> 
         </pi:EAD>
         <pi:PD>
            <pi:Code>SDF</pi:Code>
            <pi:Date>2021-02-19</pi:Date>
            <pi:Amt>40</pi:Amt>
         </pi:PD>
         <pi:PD>
            <pi:Code>SDB</pi:Code>
            <pi:Date>2021-02-26</pi:Date>
            <pi:Amt>32</pi:Amt>
         </pi:PD>
      </pi:EMP>
   </pi:PG>
</pi:PEE>

推荐阅读