2013-07-15 46 views
0

我有一个输入XMLXSLT转换,分组和总和

<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基于学生名称并获得它们的标记的总和。

回答

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> 
+0

在课堂上,我也教基于变量的分组方法,在您创建组时用到n组。当只有一组时,可以使用这种方法,但Muenchian方法更快。 –

+0

嗨... G.肯·霍尔曼非常感谢你的答复。你可以在for-each中解释选择表达式并选择元素的值。 – user2583865

+0

'sum()'的参数是'key('学生名',名称)/ marks [数字(。)=数字(。)]'这就是说:查找关键表中的所有学生与组的名称元素同名,得到所有''元素子元素,并且只保留那些有效数字。如果你相信标记是正确记录的,那么最后一位可以省略,但如果不是的话,则谓词保护总数免受“非数字”(NaN)的损害。 –

1

在XLST 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> 
+0

感谢reply..is有没有什么办法可以使用xslt 1.0来实现相同的功能我没有 available .. – user2583865

+0

是的,@Ken描述了这种方法 –