XSL v.1,Muenchian分组,每个发票汇总行项目,呼叫模板

时间:2015-06-09 13:57:39

标签: sum xslt-1.0 muenchian-grouping

我正在尝试将具有多个组的组中的订单项金额汇总。也就是说,有许多发票,每个发票都有许多行项目。我需要在每个发票中汇总行项目金额。

我在Stack上搜索了各种帖子以及各种论坛,并且无法破译代码以便能够使用Muenchian Grouping方法对值进行求和。如果已有解决方案,请指出正确的方向。

分组发生在recordId属性上。

XML:

<?xml version="1.0" encoding="UTF-8"?>
<query>
    <results total="6">
        <result recordId="15918960" associatedRecordId="null" boId="10002385">
            <columns>
                <column>
                    <field>AmountNU</field>
                    <LI_Amount_display><![CDATA[$20.74]]></LI_Amount_display>
                </column>
            </columns>
        </result>
        <result recordId="15918960" associatedRecordId="null" boId="10002385">
            <columns>
                <column>
                    <field>AmountNU</field>
                    <LI_Amount_display><![CDATA[$30.74]]></LI_Amount_display>
                </column>
            </columns>
        </result>
        <result recordId="15918960" associatedRecordId="null" boId="10002385">
            <columns>
                <column>
                    <field>AmountNU</field>
                    <LI_Amount_display><![CDATA[$40.74]]></LI_Amount_display>
                </column>
            </columns>
        </result>
        <result recordId="15918961" associatedRecordId="null" boId="10002385">
            <columns>
                <column>
                    <field>AmountNU</field>
                    <LI_Amount_display><![CDATA[$20.74]]></LI_Amount_display>
                </column>
            </columns>
        </result>
        <result recordId="15918961" associatedRecordId="null" boId="10002385">
            <columns>
                <column>
                    <field>AmountNU</field>
                    <LI_Amount_display><![CDATA[$30.74]]></LI_Amount_display>
                </column>
            </columns>
        </result>
        <result recordId="15918962" associatedRecordId="null" boId="10002385">
            <columns>
                <column>
                    <field>AmountNU</field>
                    <LI_Amount_display><![CDATA[$29.74]]></LI_Amount_display>
                </column>
            </columns>
        </result>       
    </results>
</query>

XSL:

<?xml version="1.0" encoding="UTF-8"?>

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"
xmlns:datetime="http://exslt.org/dates-and-times"
xmlns:exsl="http://exslt.org/common"
xmlns:fn="http://www.w3.org/2013/xpath-functions"
exclude-result-prefixes="datetime">
    <xsl:output method="text" encoding="UTF-8" indent="no"/>

    <xsl:key name="recordID" match="result" use="@recordId"/><!-- Define a key to use for grouping the results -->
    <!-- Might be needed for nulls 
    <xsl:template match="/results/result/columns/column/LI_Amount_display[not(text()[normalize-space()])]"> 
    <xsl:element name='LI_Amount_display' value="0.00"></xsl:element> 
    </xsl:template> -->    

    <xsl:template match="/">
        <xsl:call-template name="fixTheWidth" >
            <!-- This parameter is a Id for each group of records based on the result/@recordId attribute. This groups all records to the record ID-->
            <xsl:with-param name="resultIndex" select="//results/result[generate-id(.) = generate-id(key('recordID', @recordId)[1])]" />
        </xsl:call-template>
    </xsl:template>

    <xsl:template name="fixTheWidth" match="/results">
        <xsl:param name="resultIndex" /> <!-- A unique index based on grouping the records on the recordID -->

<!-- MORE CODE HERE USING $resultIndex has been redacted for simplicity-->

        <xsl:for-each select="$resultIndex" >
            <xsl:text> BEGIN | </xsl:text>
                <xsl:value-of select="number(translate(substring(key('recordID',@recordId)/columns/column/LI_Amount_display,2),',',''))"></xsl:value-of>
                <!-- <xsl:value-of select="sum(number(translate(substring(key('recordID',@recordId)/columns/column/LI_Amount_display,2),',','')))"></xsl:value-of>-->
        </xsl:for-each>   
         <xsl:text> | END  </xsl:text>


<!-- MORE CODE HERE USING $resultIndex has been redacted for simplicity-->


    </xsl:template>
</xsl:stylesheet>

我意识到使用“调用模板”策略不一定是“最佳”方法,但我所得到的是这样我可以创建一个固定宽度的平面文件而不必重构整个脚本。如果有办法实现这一目标,我会全力以赴。

1 个答案:

答案 0 :(得分:1)

您不能对不是数字的节点求和。值$20.74是字符串,而不是数字。您必须首先通过删除货币符号(以及任何其他非数字字符,如果输入中允许它们)将值转换为数字,然后继续对结果节点进行分组并对组进行求和。

以下是一个例子:

XSLT 1.0

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"
xmlns:exsl="http://exslt.org/common"
exclude-result-prefixes="exsl">
<xsl:output method="text" encoding="UTF-8"/>

<xsl:key name="amt" match="amount" use="@id"/>

<xsl:template match="/query">
    <xsl:variable name="amounts">
        <xsl:for-each select="results/result">
            <amount id="{@recordId}"><xsl:value-of select="translate(columns/column/LI_Amount_display, '$', '')"/></amount>
        </xsl:for-each>
    </xsl:variable>
    <xsl:variable name="amount-set" select="exsl:node-set($amounts)/amount" />

    <xsl:for-each select="$amount-set[generate-id() = generate-id(key('amt', @id)[1])]" >
        <xsl:text> BEGIN | </xsl:text>
        <xsl:value-of select="sum(key('amt', @id))"/>
    </xsl:for-each>   
    <xsl:text> | END  </xsl:text> 
</xsl:template>

</xsl:stylesheet>

应用于您的示例输入,结果为:

 BEGIN | 92.22 BEGIN | 51.48 BEGIN | 29.74 | END  

我无法理解调用模板的策略,并且&#34;创建一个固定宽度的平面文件&#34;。无论如何,它似乎与手头的问题无关。如有必要,您可以发布单独的问题。