首页 > 解决方案 > 基于新值分组

问题描述

我正在做转换,我想通过新站点值添加值。仓库 150 和仓库 120 变成美国站点,而欧盟站点只有仓库 405。我该怎么做?

输入:

<Recordname>
    <fld1>product1</fld1>
    <fld2>warehouse150</fld2>
    <fld3>13</fld3>
</Recordname>
<Recordname>
    <fld1>product1</fld1>
    <fld2>warehouse120</fld2>
    <fld3>12</fld3>
</Recordname>
<Recordname>
    <fld1>product1</fld1>
    <fld2>warehouse405</fld2>
    <fld3>22</fld3>
</Recordname>
<Recordname>
    <fld1>product1</fld1>
    <fld2>warehouse405</fld2>
    <fld3>2</fld3>
</Recordname>
<Recordname>
    <fld1>product2</fld1>
    <fld2>warehouse150</fld2>
    <fld3>7</fld3>
</Recordname>
<Recordname>
    <fld1>product2</fld1>
    <fld2>warehouse405</fld2>
    <fld3>6</fld3>
</Recordname>

输出:

<Recordname>
    <fld1>product1</fld1>
    <site>US</site>
    <fld3>25</fld3>
</Recordname>
<Recordname>
    <fld1>product1</fld1>
    <site>EU</site>
    <fld3>24</fld3>
</Recordname>
<Recordname>
    <fld1>product2</fld1>
    <site>US</site>
    <fld3>7</fld3>
</Recordname>
<Recordname>
    <fld1>product2</fld1>
    <site>EU</site>
    <fld3>6</fld3>
</Recordname>

期待您的回答,因为我是样式表的新手。

标签: xslt

解决方案


虽然可以一次完成,但更容易 - 更易读 - 分两次完成:首先重命名fld2元素并使用您的站点名称填充它,然后按产品和站点对结果进行分组:

XSLT 2.0

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

<!-- identity transform (for all modes) -->
<xsl:template match="@*|node()" mode="#all">
    <xsl:copy>
        <xsl:apply-templates select="@*|node()" mode="#current"/>
    </xsl:copy>
</xsl:template>

<xsl:template match="/root">
     <!-- first pass -->
    <xsl:variable name="first-pass">
        <xsl:apply-templates mode="first-pass"/>
    </xsl:variable>
    <!-- output -->
    <xsl:copy>
        <!-- group by product and site -->
        <xsl:for-each-group select="$first-pass/Recordname" group-by="concat(fld1, '|', site)">
            <xsl:copy>
                <xsl:apply-templates mode="output"/>
            </xsl:copy>
        </xsl:for-each-group>
    </xsl:copy>
</xsl:template>

<!-- rename and repopulate fld2 -->
<xsl:template match="fld2" mode="first-pass">
    <site>
        <xsl:value-of select="if(.='warehouse405') then 'EU' else 'US'"/>
    </site>
</xsl:template>

<!-- sum current group -->
<xsl:template match="fld3" mode="output">
    <xsl:copy>
        <xsl:value-of select="sum(current-group()/fld3)"/>
    </xsl:copy>
</xsl:template>

</xsl:stylesheet>

演示https ://xsltfiddle.liberty-development.net/6pS2B6F/1


推荐阅读