xsl 1.0 muenchian sum到每个复合键的求和数量属性字段

时间:2019-01-16 18:43:07

标签: xslt xslt-1.0

我最近在这里发布了a question,以达到类似的要求,但是现在我需要对具有属性的xml进行分组/求和。我想根据商品和状态属性对所有数量属性值进行求和。

输入xml是:

<?xml version="1.0" encoding="UTF-8"?>
<StockAdjustments xmlns="http://vsystems.com/WS/StockAdjustments">
    <StockAdjustment Article="36282" Client="AJA" Status="" Unit="ST" Quantity="-25" ReasonCode="OVERIG" Batch="" HostLocation="C" />
    <StockAdjustment Article="36282" Client="AJA" Status="QUARANTAINE" Unit="ST" Quantity="25" ReasonCode="OVERIG" Batch="" HostLocation="C" />
    <StockAdjustment Article="36282" Client="AJA" Status="" Unit="ST" Quantity="-25" ReasonCode="OVERIG" Batch="" HostLocation="C" />
    <StockAdjustment Article="36282" Client="AJA" Status="QUARANTAINE" Unit="ST" Quantity="25" ReasonCode="OVERIG" Batch="" HostLocation="C" />
    <StockAdjustment Article="36282" Client="AJA" Status="" Unit="ST" Quantity="-25" ReasonCode="OVERIG" Batch="" HostLocation="C" />
    <StockAdjustment Article="36282" Client="AJA" Status="QUARANTAINE" Unit="ST" Quantity="25" ReasonCode="OVERIG" Batch="" HostLocation="C" />
</StockAdjustments>

请求的输出是:

<?xml version="1.0" encoding="UTF-8"?>
<StockAdjustments xmlns="http://vsystems.com/WS/StockAdjustments">
    <StockAdjustment Article="36282" Client="AJA" Status="" Unit="ST" Quantity="-75" ReasonCode="OVERIG" Batch="" HostLocation="C" />
    <StockAdjustment Article="36282" Client="AJA" Status="QUARANTAINE" Unit="ST" Quantity="75" ReasonCode="OVERIG" Batch="" HostLocation="C" />
</StockAdjustments>

我创建的xsl(目前还无法正常工作):

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:iws="http://vsystems.com/WS/StockAdjustments"
exclude-result-prefixes="iws">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>


<xsl:key name="k1" match="/iws:StockAdjustment" use="concat(@Article, '|', @Status)"/>


<xsl:template match="/iws:StockAdjustments">
<xsl:copy> 
22
        <xsl:for-each select="/iws:StockAdjustment[generate-id()=generate-id(key('k1', concat(@Article,'|',@Status))[1])]">
            <xsl:copy>
                <xsl:copy-of select="@Article"/>
                <QTY_EXPE>
                    <xsl:value-of select="sum(key('k1', concat(@Article,'|',@Status))/@Quantity)" />
                </QTY_EXPE>
            </xsl:copy>
        </xsl:for-each>
    </xsl:copy>
</xsl:template>

</xsl:stylesheet>

xsl 1.0(SAP PO)

2 个答案:

答案 0 :(得分:2)

您正在滥用/符号。尝试这种方式:

XSLT 1.0

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:iws="http://vsystems.com/WS/StockAdjustments"
exclude-result-prefixes="iws">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>

<xsl:key name="k1" match="iws:StockAdjustment" use="concat(@Article, '|', @Status)"/>

<xsl:template match="/iws:StockAdjustments">
    <xsl:copy> 
        <xsl:for-each select="iws:StockAdjustment[generate-id()=generate-id(key('k1', concat(@Article,'|',@Status))[1])]">
            <xsl:copy>
                <xsl:copy-of select="@Article"/>
                <QTY_EXPE>
                    <xsl:value-of select="sum(key('k1', concat(@Article,'|',@Status))/@Quantity)" />
                </QTY_EXPE>
            </xsl:copy>
        </xsl:for-each>
    </xsl:copy>
</xsl:template>

</xsl:stylesheet>

结果不是您发布的内容,但是我尝试了您的尝试。无论如何,总和都是正确的。

答案 1 :(得分:1)

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    version="1.0" xmlns:mn="http://vsystems.com/WS/StockAdjustments">
    <xsl:strip-space elements="*"/>
    <xsl:output indent="yes" />
    <xsl:template match="mn:StockAdjustments">
      <xsl:copy>
          <xsl:apply-templates/>
      </xsl:copy>
    </xsl:template>

    <xsl:template match="mn:StockAdjustment[@Status = ''][1]">
        <xsl:copy> 
            <xsl:if test="@Article">
                <xsl:attribute name="Article">
                    <xsl:value-of select="@Article"/>
                </xsl:attribute>
            </xsl:if>
            <xsl:if test="@Client">
                <xsl:attribute name="Client">
                    <xsl:value-of select="@Client"/>
                </xsl:attribute>
            </xsl:if>
            <xsl:if test="@Status">
                <xsl:attribute name="Status">
                    <xsl:value-of select="@Status"/>
                </xsl:attribute>
            </xsl:if>
            <xsl:if test="@Unit">
                <xsl:attribute name="Unit">
                    <xsl:value-of select="@Unit"/>
                </xsl:attribute>
            </xsl:if>
            <xsl:if test="@Status = ''">
                <xsl:attribute name="Quantity">
                    <xsl:value-of select="sum(//mn:StockAdjustment[@Status = '']/@Quantity)"/>
                </xsl:attribute>
            </xsl:if>
            <xsl:if test="@ReasonCode">
                <xsl:attribute name="ReasonCode">
                    <xsl:value-of select="@ReasonCode"/>
                </xsl:attribute>
            </xsl:if>
            <xsl:if test="@Batch">
                <xsl:attribute name="Batch">
                    <xsl:value-of select="@Batch"/>
                </xsl:attribute>
            </xsl:if>
            <xsl:if test="@HostLocation">
                <xsl:attribute name="HostLocation">
                    <xsl:value-of select="@HostLocation"/>
                </xsl:attribute>
            </xsl:if>
            <xsl:apply-templates/>
        </xsl:copy>
    </xsl:template>
    <xsl:template match="mn:StockAdjustment[@Status = 'QUARANTAINE'][1]">
        <xsl:copy>
            <xsl:if test="@Article">
                <xsl:attribute name="Article">
                    <xsl:value-of select="@Article"/>
                </xsl:attribute>
            </xsl:if>
            <xsl:if test="@Client">
                <xsl:attribute name="Client">
                    <xsl:value-of select="@Client"/>
                </xsl:attribute>
            </xsl:if>
            <xsl:if test="@Status">
                <xsl:attribute name="Status">
                    <xsl:value-of select="@Status"/>
                </xsl:attribute>
            </xsl:if>
            <xsl:if test="@Unit">
                <xsl:attribute name="Unit">
                    <xsl:value-of select="@Unit"/>
                </xsl:attribute>
            </xsl:if>
            <xsl:if test="@Status = 'QUARANTAINE'">
                <xsl:attribute name="Quantity">
                    <xsl:value-of select="sum(//mn:StockAdjustment[@Status = 'QUARANTAINE']/@Quantity)"/>
                </xsl:attribute>
            </xsl:if>
            <xsl:if test="@ReasonCode">
                <xsl:attribute name="ReasonCode">
                    <xsl:value-of select="@ReasonCode"/>
                </xsl:attribute>
            </xsl:if>
            <xsl:if test="@Batch">
                <xsl:attribute name="Batch">
                    <xsl:value-of select="@Batch"/>
                </xsl:attribute>
            </xsl:if>
            <xsl:if test="@HostLocation">
                <xsl:attribute name="HostLocation">
                    <xsl:value-of select="@HostLocation"/>
                </xsl:attribute>
            </xsl:if>
            <xsl:apply-templates/>
        </xsl:copy>
    </xsl:template>

</xsl:stylesheet> 
please check if it is suitable for you.