在一个查询中汇总和翻译

时间:2018-01-09 19:41:47

标签: xml xslt

现在我遇到了另一个xml文件的问题。在此文件中,数量采用逗号格式。我必须总结这个数额但在此之前我必须在一个点上翻译逗号。当我尝试这个我得到错误,我不能使用这两个函数我一个查询。这是我文件中的一些例子:

<POSITION>
   <LINE ID="1" ID_ARTICLE="1050" QUANTITY="7,2" NET_VALUE="19,44" GROUP_ID="1"/>
   <LINE ID="2" ID_ARTICLE="812" QUANTITY="1,45" NET_VALUE="38,28" GROUP_ID="1"/>
   <LINE ID="1" ID_ARTICLE="852" QUANTITY="8,25" NET_VALUE="31,47" GROUP_ID="2"/>
   <LINE ID="2" ID_ARTICLE="812" QUANTITY="2,58" NET_VALUE="65,87" GROUP_ID="2"/>   
<POSITION>

和我的转换xml 1.0的一部分与fonction sum和translate:

sum(translate(POSITION/LINE/@NET_VALUE,'.',','))

Joel帮我总结和翻译,但是如何改变Joel的解决方案,最终结果看起来像这样:

<GROUP_ID>1</GROUP_ID>
<SUM_GROUP_ID>57,72<SUM_GROUP_ID>
<GROUP_ID>2</GROUP_ID>
<SUM_GROUP_ID>97,34<SUM_GROUP_ID>

也许有人可以帮我解决这个问题。我在此链接Using sum() function for string nodes in XSLT上找到了一些解决方案,但我无法在我的代码上实现此功能。我认为有人可以翻译这个解决方案对我来说更容易理解。我认为我仍然是xslt的初学者,尽管我对客户的文件进行了一些转换。我要求你理解。谢谢

2 个答案:

答案 0 :(得分:1)

我改编了jelovirt's answer。样式表如下。

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    version="1.0">

<xsl:template match="/POSITION">
    <xsl:call-template name="sum">
        <xsl:with-param name="node" select="LINE[1]"/>
    </xsl:call-template>
</xsl:template>

<xsl:template name="sum">
    <xsl:param name="node"/>
    <xsl:param name="sum" select="0"/>
    <xsl:choose>
        <xsl:when test="$node">
            <xsl:call-template name="sum">
                <xsl:with-param name="node" select="$node/following-sibling::LINE[1]"/>
                <xsl:with-param name="sum" select="$sum + translate($node/@NET_VALUE, ',', '.')"/>
            </xsl:call-template>
        </xsl:when>
        <xsl:otherwise>
            <xsl:value-of select="$sum"/>
        </xsl:otherwise>
    </xsl:choose>
</xsl:template>

</xsl:stylesheet>

看看它是否可以解决您的问题。

修改

为了达到新的要求,我使用xsl:key以某种方式模仿Muenchian分组。这是关键:

<xsl:key name="kID" match="LINE" use="@GROUP_ID"/>

每个唯一GROUP_ID的循环,并获取具有该唯一ID的第一个元素可以显示为

<xsl:for-each select="LINE[generate-id(.)=generate-id(key('kID', @GROUP_ID)[1])]">

现在,在我们调用模板时,我们必须将GROUP_ID作为附加参数传递,例如

<xsl:call-template name="sum">
    <xsl:with-param name="node" select="."/>
    <xsl:with-param name="group" select="@GROUP_ID"/>
</xsl:call-template>

整个样式表如下:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    version="1.0">

    <xsl:strip-space elements="*"/>
    <xsl:output indent="yes" omit-xml-declaration="yes"/>

    <xsl:key name="kID" match="LINE" use="@GROUP_ID"/>

    <xsl:template match="/POSITION">
        <xsl:for-each select="LINE[generate-id(.)=generate-id(key('kID', @GROUP_ID)[1])]">
            <GROUP_ID><xsl:value-of select="@GROUP_ID"/></GROUP_ID>
            <xsl:element name="{concat('SUM_GROUP_ID', @GROUP_ID)}">
                <xsl:call-template name="sum">
                    <xsl:with-param name="node" select="."/>
                    <xsl:with-param name="group" select="@GROUP_ID"/>
                </xsl:call-template>
            </xsl:element>
        </xsl:for-each>
    </xsl:template>

    <xsl:template name="sum">
        <xsl:param name="node"/>
        <xsl:param name="sum" select="0"/>
        <xsl:param name="group"/>
        <xsl:choose>
            <xsl:when test="$node">
                <xsl:call-template name="sum">
                    <xsl:with-param name="node" select="$node/following-sibling::LINE[$group = @GROUP_ID]"/>
                    <xsl:with-param name="sum" select="$sum + translate($node/@NET_VALUE, ',', '.')"/>
                    <xsl:with-param name="group" select="@GROUP_ID"/>
                </xsl:call-template>
            </xsl:when>
            <xsl:otherwise>
                <xsl:value-of select="$sum"/>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:template>

</xsl:stylesheet>

当这个应用于此输入时:

<POSITION>
    <LINE ID="1" ID_ARTICLE="1050" QUANTITY="7,2" NET_VALUE="19,44" GROUP_ID="1"/>
    <LINE ID="2" ID_ARTICLE="812" QUANTITY="1,45" NET_VALUE="38,28" GROUP_ID="1"/>
    <LINE ID="1" ID_ARTICLE="852" QUANTITY="8,25" NET_VALUE="31,47" GROUP_ID="2"/>
    <LINE ID="2" ID_ARTICLE="812" QUANTITY="2,58" NET_VALUE="65,87" GROUP_ID="2"/>   
</POSITION>

部分实现了所需的输出。只需用逗号替换点。

<GROUP_ID>1</GROUP_ID>
<SUM_GROUP_ID1>57.72</SUM_GROUP_ID1>
<GROUP_ID>2</GROUP_ID>
<SUM_GROUP_ID2>97.34</SUM_GROUP_ID2>

答案 1 :(得分:0)

如果您正在使用XSLT 2.0,那么很简单:请参阅Martin Honnen的评论。

如果您遇到XSLT 1.0,请参阅Sum of Multiplied Values

它在1.0中很棘手的原因是数字集合没有数据类型,只有节点集合。