XSLT转换分组和求和

时间:2013-07-15 14:39:36

标签: xslt

我有输入xml

<students>
  <student>
  <name>John</name>
  <marks>100</marks>
</student>
<student>
  <name>Arvind</name>
  <marks>90</marks>
</student>
<student>
  <name>John</name>
  <marks>100</marks>
</student>
<student>
  <name>Arvind</name>
  <marks>80</marks>
</student>
</students>

我希望将上面的xml转换为

<students>
   <student>
     <name>John</name>
    <totalMarks>200</marks>
   </student>
   <student>
     <name>Arvind</name>
    <totalMarks>170</marks>
  </student>
 </students>

所以基本上我想根据学生姓名对输入xml进行分组,并获得他们的分数总和。

2 个答案:

答案 0 :(得分:1)

在xslt 2.0中,您可以使用for-each-group

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fo="http://www.w3.org/1999/XSL/Format">
    <xsl:output method="xml" indent="yes" />

    <xsl:template match="/">
        <students>
            <xsl:apply-templates select="students" />
        </students>
    </xsl:template>

    <xsl:template match="students">
        <xsl:for-each-group select="student" group-by="name">
            <student>
                <name>
                    <xsl:value-of select="current-grouping-key()" />
                </name>
                <totalMarks>
                    <xsl:value-of select="sum(current-group()/marks)" />
                </totalMarks>
            </student>
        </xsl:for-each-group>
    </xsl:template>

</xsl:stylesheet>

答案 1 :(得分:1)

在XSLT 1中,当有一个密钥时,通常使用Muenchian分组方法:

t:\ftemp>type students.xml
<students>
  <student>
  <name>John</name>
  <marks>100</marks>
</student>
<student>
  <name>Arvind</name>
  <marks>90</marks>
</student>
<student>
  <name>John</name>
  <marks>100</marks>
</student>
<student>
  <name>Arvind</name>
  <marks>80</marks>
</student>
</students>
t:\ftemp>xslt students.xml students.xsl
<?xml version="1.0" encoding="utf-8"?>
<students>
   <student>
      <name>John</name>
      <totalMarks>200</totalMarks>
   </student>
   <student>
      <name>Arvind</name>
      <totalMarks>170</totalMarks>
   </student>
</students>
t:\ftemp>type students.xsl
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  version="1.0">

<xsl:key name="students-by-name" match="student" use="name"/>

<xsl:output indent="yes"/>

<xsl:template match="students">
  <students>
    <xsl:for-each
        select="student[generate-id(.)=
                        generate-id(key('students-by-name',name)[1])]">
      <student>
        <xsl:copy-of select="name"/>
        <totalMarks>
          <xsl:value-of select="sum(key('students-by-name',name)/marks
                                    [number(.)=number(.)])"/>
        </totalMarks>
      </student>
    </xsl:for-each>
  </students>
</xsl:template>

</xsl:stylesheet>
t:\ftemp>