Xslt 如何在xsl中按每个类别汇总值?

Xslt 如何在xsl中按每个类别汇总值?,xslt,Xslt,我需要从我们的合作伙伴xml中按地点总结销售情况(不知道提前多少个地点): 样本输入: <company> <deparment dept="001"> <location> <locationCode>001</locationCode> <sales>10000</sales> </location>

我需要从我们的合作伙伴xml中按地点总结销售情况(不知道提前多少个地点):

样本输入:

<company>
    <deparment dept="001">
        <location>
            <locationCode>001</locationCode>
            <sales>10000</sales>
        </location>
        <location>
            <locationCode>0005</locationCode>
            <sales>12500</sales>
        </location>
    </deparment>
    <deparment dept="002">
        <location>
            <locationCode>001</locationCode>
            <sales>40000</sales>
        </location>
        <location>
            <locationCode>004</locationCode>
            <sales>30000</sales>
        </location>
    </deparment>
    <deparment dept="003">
        <location>
            <locationCode>004</locationCode>
            <sales>60000</sales>
        </location>
    </deparment>
</company>

001
10000
0005
12500
001
40000
004
30000
004
60000
预期产出:

<location>
    <locationCode>001</locationCode>
    <totalSales>50000</locationCode>
<location>
<location>
    <locationCode>005</locationCode>
    <totalSales>12500</locationCode>
<location>
<location>
    <locationCode>004</locationCode>
    <totalSales>90000</locationCode>
<location>

001
50000
005
12500
004
90000
xsl是否有类似GROUPBY的功能?我是xsl新手,非常感谢您的帮助


谢谢。

我用它为XSLT1.0工作

<xsl:key name="Location" match="/company/deparment/location" use="locationCode"/>

<xsl:template match="company">
  <company>
  <xsl:for-each select="./deparment/location[generate-id() = generate-id(key('Location', ./locationCode)[1])]">
    <xsl:variable name="LocationCode" select="./locationCode"/>
    <location>
      <locationCode>
        <xsl:value-of select="$LocationCode"/>
      </locationCode>
      <totalSales>
        <xsl:value-of select="sum(//location[locationCode = $LocationCode]/sales)"/>
      </totalSales>
    </location>
  </xsl:for-each>
  </company>
</xsl:template>


在将来检查类似问题

对于XSLT2.0(带有xsl:For each group说明):


这将是一个使用XSLT 2.0的解决方案:

对于以下输入XML:

<?xml version="1.0" encoding="UTF-8"?>
<company>
    <department dept="001">
        <location>
            <locationCode>001</locationCode>
            <sales>10000</sales>
        </location>
        <location>
            <locationCode>0005</locationCode>
            <sales>12500</sales>
        </location>
    </department>
    <department dept="002">
        <location>
            <locationCode>001</locationCode>
            <sales>40000</sales>
        </location>
        <location>
            <locationCode>004</locationCode>
            <sales>30000</sales>
        </location>
    </department>
    <department dept="003">
        <location>
            <locationCode>004</locationCode>
            <sales>60000</sales>
        </location>
    </department>
</company>

001
10000
0005
12500
001
40000
004
30000
004
60000
使用以下XSLT:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes" />
<xsl:template match="/company">
<company>
    <xsl:for-each-group select="department/location" group-by="locationCode">
        <location>
            <locationCode><xsl:value-of select="current-grouping-key()"/></locationCode>
            <totalSales><xsl:value-of select="sum(current-group()/sales)"/></totalSales>
        </location>
    </xsl:for-each-group>
</company>
</xsl:template>
</xsl:stylesheet>

我得到了输出:

<?xml version="1.0" encoding="UTF-8"?>
<company xmlns:xs="http://www.w3.org/2001/XMLSchema">
    <location>
        <locationCode>001</locationCode>
        <totalSales>50000</totalSales>
    </location>
    <location>
        <locationCode>0005</locationCode>
        <totalSales>12500</totalSales>
    </location>
    <location>
        <locationCode>004</locationCode>
        <totalSales>90000</totalSales>
    </location>
</company>

001
50000
0005
12500
004
90000

一个简短、简单、高效的XSLT1.0解决方案(无变量,无
xsl:for each

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>

 <xsl:key name="kLocById" match="location" use="locationCode"/>

 <xsl:template match=
  "location
    [generate-id()
    =
     generate-id(key('kLocById',locationCode)[1])
    ]">
  <location>
   <xsl:copy-of select="locationCode"/>
   <totalSales>
    <xsl:value-of select="sum(key('kLocById',locationCode)/sales)"/>
   </totalSales>
  </location>
 </xsl:template>
 <xsl:template match="text()"/>
</xsl:stylesheet>
<company>
    <deparment dept="001">
        <location>
            <locationCode>001</locationCode>
            <sales>10000</sales>
        </location>
        <location>
            <locationCode>0005</locationCode>
            <sales>12500</sales>
        </location>
    </deparment>
    <deparment dept="002">
        <location>
            <locationCode>001</locationCode>
            <sales>40000</sales>
        </location>
        <location>
            <locationCode>004</locationCode>
            <sales>30000</sales>
        </location>
    </deparment>
    <deparment dept="003">
        <location>
            <locationCode>004</locationCode>
            <sales>60000</sales>
        </location>
    </deparment>
</company>
<location>
   <locationCode>001</locationCode>
   <totalSales>50000</totalSales>
</location>
<location>
   <locationCode>0005</locationCode>
   <totalSales>12500</totalSales>
</location>
<location>
   <locationCode>004</locationCode>
   <totalSales>90000</totalSales>
</location>

当此转换应用于提供的XML文档时

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>

 <xsl:key name="kLocById" match="location" use="locationCode"/>

 <xsl:template match=
  "location
    [generate-id()
    =
     generate-id(key('kLocById',locationCode)[1])
    ]">
  <location>
   <xsl:copy-of select="locationCode"/>
   <totalSales>
    <xsl:value-of select="sum(key('kLocById',locationCode)/sales)"/>
   </totalSales>
  </location>
 </xsl:template>
 <xsl:template match="text()"/>
</xsl:stylesheet>
<company>
    <deparment dept="001">
        <location>
            <locationCode>001</locationCode>
            <sales>10000</sales>
        </location>
        <location>
            <locationCode>0005</locationCode>
            <sales>12500</sales>
        </location>
    </deparment>
    <deparment dept="002">
        <location>
            <locationCode>001</locationCode>
            <sales>40000</sales>
        </location>
        <location>
            <locationCode>004</locationCode>
            <sales>30000</sales>
        </location>
    </deparment>
    <deparment dept="003">
        <location>
            <locationCode>004</locationCode>
            <sales>60000</sales>
        </location>
    </deparment>
</company>
<location>
   <locationCode>001</locationCode>
   <totalSales>50000</totalSales>
</location>
<location>
   <locationCode>0005</locationCode>
   <totalSales>12500</totalSales>
</location>
<location>
   <locationCode>004</locationCode>
   <totalSales>90000</totalSales>
</location>

001
10000
0005
12500
001
40000
004
30000
004
60000
生成所需的正确结果

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>

 <xsl:key name="kLocById" match="location" use="locationCode"/>

 <xsl:template match=
  "location
    [generate-id()
    =
     generate-id(key('kLocById',locationCode)[1])
    ]">
  <location>
   <xsl:copy-of select="locationCode"/>
   <totalSales>
    <xsl:value-of select="sum(key('kLocById',locationCode)/sales)"/>
   </totalSales>
  </location>
 </xsl:template>
 <xsl:template match="text()"/>
</xsl:stylesheet>
<company>
    <deparment dept="001">
        <location>
            <locationCode>001</locationCode>
            <sales>10000</sales>
        </location>
        <location>
            <locationCode>0005</locationCode>
            <sales>12500</sales>
        </location>
    </deparment>
    <deparment dept="002">
        <location>
            <locationCode>001</locationCode>
            <sales>40000</sales>
        </location>
        <location>
            <locationCode>004</locationCode>
            <sales>30000</sales>
        </location>
    </deparment>
    <deparment dept="003">
        <location>
            <locationCode>004</locationCode>
            <sales>60000</sales>
        </location>
    </deparment>
</company>
<location>
   <locationCode>001</locationCode>
   <totalSales>50000</totalSales>
</location>
<location>
   <locationCode>0005</locationCode>
   <totalSales>12500</totalSales>
</location>
<location>
   <locationCode>004</locationCode>
   <totalSales>90000</totalSales>
</location>

001
50000
0005
12500
004
90000

解释:适当使用和模板匹配。

您使用的xsl版本是什么?Xslt2.0对每个组都有xsl:instruction@user1252779当前位置我很高兴我的回答对你有用。请考虑接受最佳答案(点击答案旁边的复选标记)。