我是XSL的新手,非常感谢处理如下结构的文件:
<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>
编辑:我想为每个学生计算每个学生的总得分m1 *(i1 + i2 + ...)+ m5 *(i1 + i2 + ...),输出是XHTML,其结构如下:
Salvatore:Balliol得分= 1 *(17.5 + 2.88 + 17.75)+ 5 *(8.8.75),Kellogg得分= 卡尔:巴利奥尔得分=,凯洛格得分=
有什么想法?
答案 0 :(得分:0)
就这么简单:
<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"/>
<强> II。如果您想保留文档的结构并只是“累计”<I>
s:
<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>
<强>解释强>:
在第二次转化中覆盖 identity rule 。
<强>更新强>:
在评论中,OP增加了一项新要求:每个大学必须有每个/学生的值,每个对应的i
的值必须乘以“权重” - 其父级的值{{ 1}}。
这是一个XSLT 2.0解决方案 - 它比两遍XSLT 1.0解决方案更容易编写:
m
在新提供的XML文档上应用此转换时:
<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>
产生了想要的正确结果:
<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>