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 > 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>
但它不是 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>
我有这个来源 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 > 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>
但它不是 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>