1

我是 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 分数 = Karl: Balliol 分数 =, Kellogg 分数 =

有什么想法吗?

4

1 回答 1

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"/>

二、如果您想保留文档的结构并仅“汇总” <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>

说明

  1. 使用Muenchian 分组方法

  2. 在第二个转换中覆盖身份规则。


更新

在评论中,OP 增加了一个新要求:每所大学必须有 per/student 值,并且每个对应的值i必须乘以“权重”——其 parent 的值m

这是一个 XSLT 2.0 解决方案——它比两遍 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>
于 2013-03-31T17:35:12.170 回答