Xml 在一个查询中求和并转换

Xml 在一个查询中求和并转换,xml,xslt,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"

现在我遇到了另一个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>
Joel帮助我进行concat求和和和翻译,但如何转换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>
1
57,72
2.
97,34

也许有人能帮我解决这个问题。我在这个链接上找到了一些解决方案,但我无法在我的代码上实现。我想有人能把这个解决方案翻译得更容易理解。我认为我仍然是xslt的初学者,尽管我为客户的文件编写了一些转换。我请求你的理解。谢谢

如果您使用的是XSLT2.0,这很简单:请参阅Martin Honnen的评论

如果您坚持使用XSLT1.0,请参阅

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

我已经适应了。样式表如下所示

<?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>
每个唯一的组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
57.72
2.
97.34

我无法在我的代码上实现此功能。。。请发布更完整的代码,而不是一行代码片段。然后我们可以看到您的实现。您使用XML1.0还是XSLT1.0?如果使用XSLT 2或更高版本,您可以轻松地编写
sum(/POSITION/LINE/@NET_VALUE/number(translate(,,,,,,,,))
。如果您仅限于XSLT1,那么告诉我们您使用的XSLT1处理器可能会有所帮助。在这个处理器上,我只能使用基本功能,更多的功能我必须用模板来编写。听起来是时候转移到2.0了。不幸的是,我不能转移到xslt 2.0,因为我编写转换的软件制造商,只有xslt 1.0,不可能在新版本上更改它。我的同情。我想,这还不如困在COBOL上那么糟糕,但离我们越来越近了。乔尔非常感谢这个解决方案。它工作得很好。我花了一些时间在代码中实现了这一点,但这是一个很好的解决方案。在这个例子中,我发现了另一件事。我必须对id_组进行分组求和,它位于所有行中,例如:。我是否很难在您的解决方案中采用这一点?请编辑您的问题以反映您的新要求。请参阅我答案的编辑部分。Joel you's awsome:)非常感谢您的解决方案和指导,它是如何工作的。
<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>