XSLT 2.0 中的变量分组

Grouping of variables in XSLT 2.0

对于具有相同值 <CtryCd> 的每个 <LineDetail> 节点,并用 <Amt> 的总和填充 1 <LineDetail>。 但是,我还需要检查 <SI><TI> 节点。求和的输出标签将基于 <SI><TI> 节点。如果<SI><TI>的值都为false,则生成<Amt1>,而如果<SI>的值为true且[=19,则生成<Amt2> =] 是错误的。 我创建了一个 XSLT 并且已经得到了总和。但是我的输出中仍然缺少一些东西。

这是一个示例XML:

<Record>
<Data>
    <Process>
        <Header>
            <ID>22-BBB</ID>
            <Date>2017-02-14</Date>
            <ContactName>Abegail</ContactName>
            <!-- some other elements -->
        </Header>
        <Detail>
            <ID>22-CCC</ID>
            <RequestedDate>2017-02-14</RequestedDate>
            <!-- some other elements -->
            <LineDetail>
                <CtryCd>AF</CtryCd>
                <SI>false</SI>
                <TI>false</TI>
                <Amt>11.11</Amt>
            </LineDetail>
            <LineDetail>
                <CtryCd>SE</CtryCd>
                <SI>true</SI>
                <TI>false</TI>
                <Amt>22.22</Amt>
            </LineDetail>
            <LineDetail>
                <CtryCd>AF</CtryCd>
                <SI>false</SI>
                <TI>false</TI>
                <Amt>33.33</Amt>
            </LineDetail>
            <LineDetail>
                <CtryCd>AF</CtryCd>
                <SI>true</SI>
                <TI>false</TI>
                <Amt>55.55</Amt>
            </LineDetail>       
        </Detail>
    </Process>
</Data>
</Record>

生成的输出:

<Record>
<Data>
    <Process>
        <Header>
            <ID>22-BBB</ID>
            <Date>2017-02-14</Date>
            <ContactName>Abegail</ContactName>
            <!-- some other elements -->
        </Header>
        <Detail>
            <LineDetail>
                <CtryCd>AF</CtryCd>
                <Amt1>99.99</Amt1>
            </LineDetail>
        </Detail>
        <Detail>
            <LineDetail>
                <C<Amt2>22.22</Amt2>
            </LineDetail>
        </Detail>
    </Process>
</Data>
</Record>

预期输出:

<Record>
<Data>
    <Process>
        <Header>
            <ID>22-BBB</ID>
            <Date>2017-02-14</Date>
            <ContactName>Abegail</ContactName>
            <!-- some other elements -->
        </Header>
        <Detail>
            <ID>22-CCC</ID>
            <RequestedDate>2017-02-14</RequestedDate>
            <!-- some other elements -->
            <LineDetail>
                <CtryCd>AF</CtryCd>
                <Amt1>44.44</<Amt1>
                <Amt2>55.55</Amt2>
            </LineDetail>
            <LineDetail>
                <CtryCd>SE</CtryCd>
                <Amt1>0</<Amt1>
                <Amt2>22.22</Amt2>
            </LineDetail>           
        </Detail>
    </Process>
</Data>
</Record>

XSLT:

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:key name="CtryCd" match="LineDetail" use="CtryCd"/>
<!-- identity transform -->
<xsl:template match="@*|node()">
    <xsl:copy>
        <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
</xsl:template>
<xsl:template match="Detail">
    <xsl:for-each-group select="LineDetail" group-by="CtryCd">
        <Detail>
            <LineDetail>
                <CtryCd>
                    <xsl:value-of select="CtryCd"/>
                </CtryCd>
                <xsl:if test="lower-case(SI)='false' and lower-case(TI)='false'">
                    <Amt1>
                        <xsl:value-of select="sum(current-group()/Amt)"/>
                    </Amt1>
                <xsl:if test="lower-case(SI)='true' and lower-case(TI)='false'">
                    <Amt2>
                        <xsl:value-of select="sum(current-group()/Amt)"/>
                    </Amt2>
                </xsl:if>
                </xsl:if>
                <xsl:if test="lower-case(SI)='true' and lower-case(TI)='false'">
                    <Amt2>
                        <xsl:value-of select="sum(current-group()/Amt)"/>
                    </Amt2>
                </xsl:if>
            </LineDetail>
        </Detail>
    </xsl:for-each-group>
</xsl:template>
</xsl:stylesheet>

您当前的 if 条件只会检查组中的第一项。您确实需要它成为实际总和语句的一部分,作为组中每个节点的条件。

<Amt1>
    <xsl:value-of select="sum(current-group()[lower-case(SI)='false' and lower-case(TI)='false']/Amt)"/>
</Amt1>

然后您会对 Amt2 进行类似的声明,测试 "true" 和 "false"

试试这个 XSLT

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>

<xsl:key name="CtryCd" match="LineDetail" use="CtryCd"/>

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

<xsl:template match="Detail">
    <xsl:for-each-group select="LineDetail" group-by="CtryCd">
        <Detail>
            <LineDetail>
                <CtryCd>
                    <xsl:value-of select="CtryCd"/>
                </CtryCd>
                <Amt1>
                    <xsl:value-of select="sum(current-group()[lower-case(SI)='false' and lower-case(TI)='false']/Amt)"/>
                </Amt1>
                <Amt2>
                    <xsl:value-of select="sum(current-group()[lower-case(SI)='true' and lower-case(TI)='false']/Amt)"/>
                </Amt2>
            </LineDetail>
        </Detail>
    </xsl:for-each-group>
</xsl:template>
</xsl:stylesheet>