温馨提示:本文翻译自stackoverflow.com,查看原文请点击:xml - xslt remove record based on criteria and groupBy
grouping xml xslt

xml - xslt根据条件和groupBy删除记录

发布于 2020-04-04 00:05:13

我正在艰难的xsl转换中挣扎,我不知道如何使它工作。作为输入,我有一个记录集合。每个记录由两个键(pk1和pk2)标识,并且具有限定符。目标是复制按pk1和pk2分组的那些记录。这很简单。当我只需要复制限定词A和B出现次数相同的那些词时,就会出现问题。这是输入文件。

<Data>
<!-- first case -->
<record>
    <pk1>0001</pk1>
    <pk2>AAA</pk2>
    <quantity>50.00</quantity>
    <qualifier>A</qualifier>
</record>
<!-- second case -->
<record>
    <pk1>0002</pk1>
    <pk2>AAA</pk2>
    <quantity>10.00</quantity>
    <qualifier>A</qualifier>
</record>
<record>
    <pk1>0002</pk1>
    <pk2>AAA</pk2>
    <quantity>10.00</quantity>
    <qualifier>B</qualifier>
</record>
<record>
    <pk1>0002</pk1>
    <pk2>BBB</pk2>
    <quantity>15.00</quantity>
    <qualifier>A</qualifier>
</record>
<!-- third case -->
<record>
    <pk1>0003</pk1>
    <pk2>AAA</pk2>
    <quantity>20.00</quantity>
    <qualifier>A</qualifier>
</record>
<record>
    <pk1>0003</pk1>
    <pk2>AAA</pk2>
    <quantity>20.00</quantity>
    <qualifier>B</qualifier>
</record>
<record>
    <pk1>0003</pk1>
    <pk2>AAA</pk2>
    <quantity>20.00</quantity>
    <qualifier>A</qualifier>
</record>
<record>
    <pk1>0003</pk1>
    <pk2>BBB</pk2>
    <quantity>70.00</quantity>
    <qualifier>A</qualifier>
</record>
<record>
    <pk1>0003</pk1>
    <pk2>BBB</pk2>
    <quantity>70.00</quantity>
    <qualifier>B</qualifier>
</record>
<!-- fourth case -->
<record>
    <pk1>0004</pk1>
    <pk2>AAA</pk2>
    <quantity>100.00</quantity>
    <qualifier>B</qualifier>
</record>

这是预期的输出。

<Data>
<!-- first case -->
<!-- second case -->
<record>
    <pk1>0002</pk1>
    <pk2>AAA</pk2>
    <quantity>10.00</quantity>
    <qualifier>A</qualifier>
</record>
<!-- third case -->
<record>
    <pk1>0003</pk1>
    <pk2>BBB</pk2>
    <quantity>70.00</quantity>
    <qualifier>A</qualifier>
</record>
<!-- fourth case -->

每种情况的解释为:第一种情况:0001 | AAA | A没有其对0001 | AAA | B-> remove

第二种情况:0002 | AAA | A有一对0002 | AAA | B->保持“ A”为一

第三种情况:0003 | AAA | A有其对0003 | AAA | B,但还有一个对0003 | AAA | A,这意味着对于此组,“ A”与“ B”的出现次数不同->删除

第三种情况:0003 | BBB | A有其对0003 | BBB | B->保留“ A”

第四种情况:0004 | AAA | A没有其对0004 | AAA | B->删除

就像我说的,我不知道如何实现以及如何使用xslt实现它。请你帮助我好吗?谢谢。

查看更多

提问者
James Taylor
被浏览
93
michael.hor257k 2020-01-31 20:46

考虑下面的简化示例:

XML格式

<Data>
    <!-- first case -->
    <record>
        <group>0001</group>
        <quantity>50.00</quantity>
        <qualifier>A</qualifier>
    </record>
    <!-- second case -->
    <record>
        <group>0002</group>
        <quantity>10.00</quantity>
        <qualifier>A</qualifier>
    </record>
    <record>
        <group>0002</group>
        <quantity>11.00</quantity>
        <qualifier>B</qualifier>
    </record>
    <record>
        <group>0002</group>
        <quantity>12.00</quantity>
        <qualifier>A</qualifier>
    </record>
    <record>
        <group>0002</group>
        <quantity>13.00</quantity>
        <qualifier>B</qualifier>
    </record>
    <!-- third case -->
    <record>
        <group>0003</group>
        <quantity>20.00</quantity>
        <qualifier>A</qualifier>
    </record>
    <record>
        <group>0003</group>
        <quantity>30.00</quantity>
        <qualifier>B</qualifier>
    </record>
    <record>
        <group>0003</group>
        <quantity>40.00</quantity>
        <qualifier>A</qualifier>
    </record>
</Data>

XSLT 2.0

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

<xsl:template match="/Data">
    <Data>
        <xsl:for-each-group select="record" group-by="group">
            <xsl:if test="count(current-group()[qualifier='A'])=count(current-group()[qualifier='B'])">
                <record>
                    <xsl:copy-of select="group" />
                    <quantity>
                        <xsl:value-of select="sum(current-group()/quantity)" />
                    </quantity>
                </record>
            </xsl:if>
        </xsl:for-each-group>
    </Data>
</xsl:template>

</xsl:stylesheet>

结果

<Data>
   <record>
      <group>0002</group>
      <quantity>46</quantity>
   </record>
</Data>

演示:https : //xsltfiddle.liberty-development.net/pPJ9hEe