これと同じくらい簡単です:
<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="kIByVal" match="i" use="."/>
<xsl:template match=
"i[not(generate-id()=generate-id(key('kIByVal',.)[1]))]"/>
<xsl:template match="i">
<college name="{.}" total="{sum(key('kIByVal',.)/@value)}"/>
</xsl:template>
<xsl:template match="text()"/>
</xsl:stylesheet>
この変換が提供された XML ドキュメントに適用されると、次のようになります。
<student>
<name>Salvatore</name>
<m value="1">
<i value="17.5">Balliol College</i>
<i value="3">Kellogg College</i>
<i value="2.88">Balliol College</i>
</m>
</student>
必要な正しい結果が生成されます。
<college name="Balliol College" total="20.38"/>
<college name="Kellogg College" total="3"/>
Ⅱ.ドキュメントの構造を保持し、単に s を「合計」したい場合<I>
:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:key name="kIByVal" match="i" use="."/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match=
"i[not(generate-id()=generate-id(key('kIByVal',.)[1]))]"/>
<xsl:template match="i">
<i value="{sum(key('kIByVal',.)/@value)}"><xsl:apply-templates/></i>
</xsl:template>
</xsl:stylesheet>
この変換を同じ XML ドキュメント (上記) に適用すると、再び正しい結果が生成されます。
<student>
<name>Salvatore</name>
<m value="1">
<i value="20.38">Balliol College</i>
<i value="3">Kellogg College</i>
</m>
</student>
説明:
Muenchian グループ化方法の使用。
2 番目の変換でアイデンティティ ルールをオーバーライドします。
更新:
コメントで、OP は新しい要件を追加しました。各大学には、学生ごとの値が必要であり、対応する各大学の値にi
「重み」 (親の値) を掛ける必要がありますm
。
以下は XSLT 2.0 ソリューションです。2 パスの XSLT 1.0 ソリューションよりも簡単に記述できます。
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:key name="kIByVal" match="i" use="."/>
<xsl:key name="kStudentByCollege" match="student"
use="m/i"/>
<xsl:key name="kCollegePerStudentPerM" match="i"
use="concat(generate-id(../..),'+',generate-id(..),'+',.)"/>
<xsl:template match=
"i[not(generate-id()=generate-id(key('kIByVal',.)[1]))]"/>
<xsl:template match="i">
<college name="{.}">
<xsl:apply-templates mode="college" select=
"key('kStudentByCollege', .)">
<xsl:with-param name="pCollegeName" select="."/>
</xsl:apply-templates>
</college>
</xsl:template>
<xsl:template match="student" mode="college">
<xsl:param name="pCollegeName"/>
<student name="{name}">
<xsl:sequence select=
"sum(m/(@value*sum(key('kCollegePerStudentPerM',
concat(generate-id(..),'+',
generate-id(.),'+',$pCollegeName)
)/@value
)
)
)"/>
</student>
</xsl:template>
<xsl:template match="text()"/>
</xsl:stylesheet>
この変換が新しく提供された XML ドキュメントに適用されると、次のようになります。
<UniML>
<student>
<name>Salvatore</name>
<m value="1">
<i value="17.5">Balliol College</i>
<i value="3">Kellogg College</i>
<i value="2.88">Balliol College</i>
<i value="32.9">Kellogg College</i>
<i value="15.75">Balliol College</i>
</m>
<m value="5">
<i value="26.25">Kellogg College</i>
<i value="8.75">Balliol College</i>
</m>
</student>
<student>
<name>Karl</name>
<m value="1">
<i value="10.5">Balliol College</i>
<i value="4.7">Kellogg College</i>
<i value="2.25">Balliol College</i>
<i value="12.6">Kellogg College</i>
</m>
<m value="5">
<i value="3.75">Kellogg College</i>
<i value="1.25">Balliol College</i>
</m>
</student>
<student>
<name>Serenella</name>
<m value="1">
<i value="4">Kellogg College</i>
<i value="3.84">Balliol College</i>
<i value="14.100000000000001">Kellogg College</i>
<i value="6.75">Balliol College</i>
</m>
<m value="5">
<i value="20.25">Kellogg College</i>
<i value="42.75">Balliol College</i>
<i value="11.25">Kellogg College</i>
<i value="3.75">Balliol College</i>
</m>
</student>
</UniML>
必要な正しい結果が生成されます。
<college name="Balliol College">
<student name="Salvatore">79.88</student>
<student name="Karl">19</student>
<student name="Serenella">243.09</student>
</college>
<college name="Kellogg College">
<student name="Salvatore">167.15</student>
<student name="Karl">36.05</student>
<student name="Serenella">175.6</student>
</college>