如何根据xsl中的每个类别总结值?

时间:2012-03-06 17:19:00

标签: xslt

我需要按照合作伙伴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>

预期产出:

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

xsl有类似分组的东西吗?我是xsl的新手并且感谢任何帮助。

感谢。

4 个答案:

答案 0 :(得分:1)

我用它来为xslt 1.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>

将来查看muenchian method这样的问题。

答案 1 :(得分:1)

这将是使用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>

使用以下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>

答案 2 :(得分:1)

简短而有效的XSLT 1.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>

将此转换应用于提供的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>

产生了想要的正确结果

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

解释:正确使用 Muenchian method for grouping 和模板匹配。

答案 3 :(得分:0)

对于 Xslt 2.0 (使用 xsl:for-each-group 指令):

<xsl:stylesheet 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    version="2.0" >

    <xsl:output indent="yes" />

    <xsl:template match="/">
        <xsl:for-each-group select="company/deparment/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>

    </xsl:template>  

</xsl:stylesheet>