代码之家  ›  专栏  ›  技术社区  ›  user3529643

按名称和总和值分组的XSLT

  •  1
  • user3529643  · 技术社区  · 6 年前

    输入

    <root>
    <TL>
        <msg>
            <output_getquerydata>
                <queries>
                    <query name="q1">
                        <parameters>
                            <parameter name="id">906OREA</parameter>
                        </parameters>
                        <queryErrors/>
                        <queryResults>
                            <record>
                                <column name="actionState">sdss</column>
                            </record>
                        </queryResults>
                    </query>
                    <query name="q2">
                        <parameters>
                            <parameter name="resCode">CTL-3819</parameter>
                            <parameter name="prodCode">89CMID</parameter>
                        </parameters>
                        <queryErrors/>
                        <queryResults>
                            <record id="1">
                                <column name="resource_externalId">CTL-000002</column>
                                <column name="compartmentCode">CTL-3819-01</column>
                                <column name="ExternalProductId"/>
                            </record>
                            <record id="2">
                                <column name="resource_externalId">CTL-000002</column>
                                <column name="compartmentCode">CTL-3819-02</column>
                                <column name="ExternalProductId"/>
                            </record>
                            <record id="3">
                                <column name="resource_externalId"/>
                                <column name="compartmentCode"/>
                                <column name="position"/>
                                <column name="ExternalProductId">316442</column>
                            </record>
                        </queryResults>
                    </query>
                    <query name="q2">
                        <parameters>
                            <parameter name="resCode">CTL-3819</parameter>
                            <parameter name="prodCode">91VPRM</parameter>
                        </parameters>
                        <queryErrors/>
                        <queryResults>
                            <record id="1">
                                <column name="resource_externalId">CTL-000002</column>
                                <column name="compartmentCode">CTL-3819-01</column>
                                <column name="position">1</column>
                                <column name="ExternalProductId"/>
                            </record>
                            <record id="2">
                                <column name="resource_externalId"/>
                                <column name="compartmentCode"/>
                                <column name="position"/>
                                <column name="ExternalProductId">316495</column>
                            </record>
                        </queryResults>
                    </query>
                </queries>
            </output_getquerydata>
        </msg>
        <TL>
            <id>65004</id>
            <ArticleNr>89CMID</ArticleNr>
            <Gross>2700</Gross>
        </TL>
        <TL>
            <id>65005</id>
            <ArticleNr>89CMID</ArticleNr>
            <Gross>1700</Gross>
            <BOLNumber>18117</BOLNumber>
        </TL>
        <TL>
            <id>65006</id>
            <ArticleNr>89CMID</ArticleNr>
            <Gross>2100</Gross>
            <BOLNumber>18117</BOLNumber>
        </TL>
        <TL>
            <id>65007</id>
            <ArticleNr>91VPRM</ArticleNr>
            <Gross>500</Gross>
            <BOLNumber>18117</BOLNumber>
        </TL>
    </TL>
    </root>
    

    XSL:

       <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:strip-space elements="*"/>
    <xsl:output encoding="ISO-8859-1" indent="yes" method="xml"/>
    <xsl:key name="Article" match="TL" use="./ArticleNr"/>
    <xsl:key name="prod" match="query[@name='q2']/queryResults/record" use="../../parameters/parameter[@name='prodCode']"/>
    <xsl:template match="root">
        <msglist>
            <xsl:for-each select="./TL[./msg/output_getquerydata/queries/query/queryResults/record/column[@name='actionState'] !='finished'] ">
                <xsl:variable name="distinctArticle" select="//TL[string(ArticleNr)][count(. | key('Article',ArticleNr)[1]) = 1]"/>
                <msg>
                    <CMT>
                        <m>
                            <a>
                                <AP>
                                    <xsl:variable name="position">
                                        <!--variable to concatenate all products -->
                                        <xsl:for-each select="$distinctArticle">
                                            <xsl:variable name="pos" select="concat(key('prod', .//ArticleNr)/column[@name='ExternalProductId'][. != ''],';')"/>
                                            <xsl:value-of select="$pos"/>
                                        </xsl:for-each>
                                    </xsl:variable>
                                    <xsl:for-each select="TL[generate-id() = 
                       generate-id(key('Article', .//ArticleNr)[1])]">
                                        <grossVolume>
                                            <xsl:value-of select="sum(concat(.,';'))"/>
                                        </grossVolume>
                                    </xsl:for-each>
                                    <product>
                                        <xsl:choose>
                                            <xsl:when test="substring($position, string-length($position))=';'">
                                                <xsl:value-of select="substring($position, 1, string-length($position)-1)"/>
                                            </xsl:when>
                                            <xsl:otherwise>
                                                <xsl:value-of select="$position"/>
                                            </xsl:otherwise>
                                        </xsl:choose>
                                    </product>
                                </AP>
                            </a>
                        </m>
                    </CMT>
                </msg>
            </xsl:for-each>
        </msglist>
    </xsl:template>
    </xsl:stylesheet>
    

    产量几乎不错。问题是,我需要在grossvolume节点中为同一个Articlenr获取所有“gross”节点的总和。 所以,我的输出是:

     <grossVolume>6500;500</grossVolume>
     <product>316442;316495</product>
    

    因为对于Articlenr-89cmid-,我们的总值为2700+1700+2100=6500。

    基本上,对于所有具有相同值的“Articlenr”节点,我需要从它们各自的“Gross”节点中求和所有的数字,然后生成一个输出,我们在其中连接这些总和。 对于产品节点输出,我将所需的值连接起来,并且它可以工作,我还需要在grossvolume节点中具有类似的信息。

    谢谢您!

    1 回复  |  直到 6 年前
        1
  •  1
  •   Aniket V    6 年前

    你不能做 sum() concat() 在同一条指令中,它将引发字符串和数字组合的错误。总和必须存储在一个局部变量中,然后用于与其他总和连接以形成 <grossVolume> .

    请换一下 for-each 循环 TL

    <xsl:for-each select="TL[generate-id() = generate-id(key('Article', .//ArticleNr)[1])]">
        <grossVolume>
            <xsl:value-of select="sum(concat(.,';'))"/>
        </grossVolume>
    </xsl:for-each>
    

    到以下代码段

    <grossVolume>
        <xsl:for-each select="TL[generate-id() = generate-id(key('Article', ./ArticleNr)[1])]">
            <xsl:variable name="sumGross" select="sum(key('Article', ./ArticleNr)/Gross)" />
            <xsl:value-of select="$sumGross" />
            <xsl:if test="position() != last()">
                <xsl:value-of select="';'" />
            </xsl:if>
        </xsl:for-each>
    </grossVolume>
    

    输出

    <grossVolume>6500;500</grossVolume>