I have this source XML and I have to group the <SpinRecord>
elements by <IndirectCust>
and <SalesVolume>
:
<?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>
I came up with this 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 > 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 > 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 > 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>
But it is not working 100%, I am getting this output and for <IndirectCust>
123 the positive values are not grouped together:
<?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>
My expected output would be the following:
<?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>
I am struggling with the <xsl:key>
. Do you have any idea how to make this work? Do I have to use two keys, one for positive and one for negative <SalesVolume>
?
Thank you, Peter
Could you not do simply:
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>