XSLT 1.0:使用 xsl:key 对正值和负值进行分组

XSLT 1.0: grouping positive and negative values with an xsl:key

我有这个来源 XML,我必须按 <IndirectCust><SalesVolume>:

<SpinRecord> 元素进行分组
<?xml version="1.0" encoding="UTF-8"?>
<SI_CSV_SPIN_OUT>
    <Recordset>
        <SpinRecord>
            <IndirectCust>1080360</IndirectCust>
            <SalesVolume>-2</SalesVolume>
        </SpinRecord>
        <SpinRecord>
            <IndirectCust>1080360</IndirectCust>
            <SalesVolume>-1</SalesVolume>
        </SpinRecord>
        <SpinRecord>
            <IndirectCust>1080360</IndirectCust>
            <SalesVolume>10</SalesVolume>
        </SpinRecord>
        <SpinRecord>
            <IndirectCust>123</IndirectCust>
            <SalesVolume>10</SalesVolume>
        </SpinRecord>
        <SpinRecord>
            <IndirectCust>123</IndirectCust>
            <SalesVolume>-9</SalesVolume>
        </SpinRecord>
        <SpinRecord>
            <IndirectCust>123</IndirectCust>
            <SalesVolume>8</SalesVolume>
        </SpinRecord>
    </Recordset>
</SI_CSV_SPIN_OUT>

我想到了这个 XSLT:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
   xmlns:xd="http://www.oxygenxml.com/ns/doc/xsl"
   exclude-result-prefixes="xd"
   version="1.0">   
   <xsl:output indent="yes" method="xml"/>
   
   <!-- define the key to define unique elements --> 
   <xsl:key name="keyCustGroup" match="SpinRecord" use="concat(IndirectCust, '|', self::*[SalesVolume &gt; 0])"/>
   
   <!-- define which elements are unique -->
   <xsl:template match="/*/*">
       <xsl:variable name="uniqueTransactions" select="SpinRecord[generate-id()=generate-id(key('keyCustGroup',concat(IndirectCust, '|', self::*[SalesVolume &gt; 0]))[1])]"/>
       <SI_CSV_SPIN_OUT>
           <xsl:apply-templates select="$uniqueTransactions" mode="group"/>
       </SI_CSV_SPIN_OUT>
   </xsl:template>
   
   <!-- create the unique groups -->
   <xsl:template match="SpinRecord" mode="group">
       <SpinRecords>
           <xsl:apply-templates select="key('keyCustGroup',concat(IndirectCust, '|', self::*[SalesVolume &gt; 0]))" mode="item" />
       </SpinRecords>    
   </xsl:template>
   
   <!-- write the item content into each group -->
   <xsl:template match="SpinRecord" mode="item">
       <SpinRecord>
           <xsl:copy-of select="child::*"/>
       </SpinRecord>
   </xsl:template>
   
</xsl:stylesheet>

但它不是 100% 有效,我得到了这个输出,对于 <IndirectCust> 123,正值没有组合在一起:

<?xml version="1.0" encoding="UTF-8"?>
<SI_CSV_SPIN_OUT>
    <SpinRecords>
        <SpinRecord>
            <IndirectCust>1080360</IndirectCust>
            <SalesVolume>-2</SalesVolume>
        </SpinRecord>
        <SpinRecord>
            <IndirectCust>1080360</IndirectCust>
            <SalesVolume>-1</SalesVolume>
        </SpinRecord>
    </SpinRecords>
    <SpinRecords>
        <SpinRecord>
            <IndirectCust>1080360</IndirectCust>
            <SalesVolume>10</SalesVolume>
        </SpinRecord>
    </SpinRecords>
    <SpinRecords>
        <SpinRecord>
            <IndirectCust>123</IndirectCust>
            <SalesVolume>10</SalesVolume>
        </SpinRecord>
    </SpinRecords>
    <SpinRecords>
        <SpinRecord>
            <IndirectCust>123</IndirectCust>
            <SalesVolume>-9</SalesVolume>
        </SpinRecord>
    </SpinRecords>
    <SpinRecords>
        <SpinRecord>
            <IndirectCust>123</IndirectCust>
            <SalesVolume>8</SalesVolume>
        </SpinRecord>
    </SpinRecords>
</SI_CSV_SPIN_OUT>

我的预期输出如下:

<?xml version="1.0" encoding="UTF-8"?>
<SI_CSV_SPIN_OUT>
    <SpinRecords>
        <SpinRecord>
            <IndirectCust>1080360</IndirectCust>
            <SalesVolume>-2</SalesVolume>
        </SpinRecord>
        <SpinRecord>
            <IndirectCust>1080360</IndirectCust>
            <SalesVolume>-1</SalesVolume>
        </SpinRecord>
    </SpinRecords>
    <SpinRecords>
        <SpinRecord>
            <IndirectCust>1080360</IndirectCust>
            <SalesVolume>10</SalesVolume>
        </SpinRecord>
    </SpinRecords>
    <SpinRecords>
        <SpinRecord>
            <IndirectCust>123</IndirectCust>
            <SalesVolume>10</SalesVolume>
        </SpinRecord>
        <SpinRecord>
            <IndirectCust>123</IndirectCust>
            <SalesVolume>8</SalesVolume>
        </SpinRecord>
    </SpinRecords>
    <SpinRecords>
        <SpinRecord>
            <IndirectCust>123</IndirectCust>
            <SalesVolume>-9</SalesVolume>
        </SpinRecord>
    </SpinRecords>
</SI_CSV_SPIN_OUT>

我正在为 <xsl:key> 苦苦挣扎。您知道如何进行这项工作吗?我是否必须使用两个键,一个用于正,一个用于负 <SalesVolume>?

谢谢你,彼得

能不能简单点:

XSLT 1.0

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

<xsl:key name="k1" match="SpinRecord" use="concat(IndirectCust, '|', SalesVolume > 0)"/>

<xsl:template match="/SI_CSV_SPIN_OUT">
    <xsl:copy>
        <xsl:for-each select="Recordset/SpinRecord[count(. | key('k1', concat(IndirectCust, '|', SalesVolume > 0))[1]) = 1]">
            <SpinRecords>
                <xsl:copy-of select="key('k1', concat(IndirectCust, '|', SalesVolume > 0))"/>
            </SpinRecords>
        </xsl:for-each>
    </xsl:copy>
</xsl:template>

</xsl:stylesheet>