XSLT Group Count

时间:2013-03-17 17:50:07

标签: xslt count

我在为下面的转换创建XSLT时遇到了问题。我对XSLT转换比较陌生。问题是我想在输入中计算来自不同国家的学生人数。我已经尝试根据条件进行计数,但由于此计数已分组,因此无效。有人可以告诉我是否可以做到这一点是XSLT 1.0。

我的输入是

<ns0:DetailsResponse xmlns:ns0="http://MySchema.XSLTSchema">
  <Class>1</Class>
  <Students>
    <StudentName>John</StudentName>
    <StudentSurname>Doe</StudentSurname>
    <Country>
      <CountryName>UK</CountryName>
    </Country>
  </Students>
  <Students>
    <StudentName>Cherry</StudentName>
    <StudentSurname>Blossom</StudentSurname>
    <Country>
      <CountryName>US</CountryName>
    </Country>
  </Students>
  <Students>
    <StudentName>Ankit</StudentName>
    <StudentSurname>Sood</StudentSurname>
    <Country>
      <CountryName>INDIA</CountryName>
    </Country>
  </Students>
  <Students>
    <StudentName>Peter</StudentName>
    <StudentSurname>Scott</StudentSurname>
    <Country>
      <CountryName>UK</CountryName>
    </Country>
  </Students>
  <Students>
    <StudentName>Joe</StudentName>
    <StudentSurname>Carter</StudentSurname>
    <Country>
      <CountryName>UK</CountryName>
    </Country>
  </Students>
  <Students>
    <StudentName>Anu</StudentName>
    <StudentSurname>Mehta</StudentSurname>
    <Country>
      <CountryName>INDIA</CountryName>
    </Country>
  </Students>
</ns0:DetailsResponse>

我希望我的输出像

输出

<ns0:Root xmlns:ns0="http://MySchema.XSLTSchema_Destination">
  <DestinationClass>DestinationClass_0</DestinationClass>
  <Countries>
    <CountryWiseCount>
      <Country>INDIA</Country>
      <Count>2</Count>
    </CountryWiseCount>
    <CountryWiseCount>
      <Country>UK</Country>
      <Count>3</Count>
    </CountryWiseCount>
    <CountryWiseCount>
      <Country>US</Country>
      <Count>1</Count>
    </CountryWiseCount>
  </Countries>
</ns0:Root>

1 个答案:

答案 0 :(得分:2)

如果您使用的是XSLT 1.0,那么Muenchian Grouping将成为您的朋友。

您按国家/地区名称对学生进行分组,因此您可以定义一个键来查找学生

<xsl:key name="students" match="Students" use="Country/CountryName"/>

然后,为了获得不同的国家/地区,您将匹配恰好在其指定国家/地区的密钥中首先出现的元素的学生元素。

<xsl:template 
     match="Students[generate-id() = generate-id(key('students', Country/CountryName)[1])]">

然后,要计算该国家所有学生的数量,您只需计算一下密钥:

<xsl:value-of select="count(key('students', Country/CountryName))"/>

这是完整的XSLT:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
   <xsl:output method="xml" indent="yes"/>

   <xsl:key name="students" match="Students" use="Country/CountryName"/>

   <xsl:template match="Students[generate-id() = generate-id(key('students', Country/CountryName)[1])]">
      <CountryWiseCount>
         <Country>
            <xsl:value-of select="Country/CountryName"/>
         </Country>
         <Count>
            <xsl:value-of select="count(key('students', Country/CountryName))"/>
         </Count>
      </CountryWiseCount>
   </xsl:template>

   <xsl:template match="Students"/>

   <xsl:template match="@*|node()">
      <xsl:copy>
         <xsl:apply-templates select="@*|node()"/>
      </xsl:copy>
   </xsl:template>
</xsl:stylesheet>

应用于XML时,输出以下内容

<ns0:DetailsResponse xmlns:ns0="http://MySchema.XSLTSchema">
   <Class>1</Class>
   <CountryWiseCount>
      <Country>UK</Country>
      <Count>3</Count>
   </CountryWiseCount>
   <CountryWiseCount>
      <Country>US</Country>
      <Count>1</Count>
   </CountryWiseCount>
   <CountryWiseCount>
      <Country>INDIA</Country>
      <Count>2</Count>
   </CountryWiseCount>
</ns0:DetailsResponse>

请注意,使用与学生元素匹配的模板<xsl:template match="Students"/>来阻止它们输出。 XSLT将始终优先使用更具体的模板(使用xpath表达式),因此该模板不会忽略所有内容。

显然,您需要使用模板扩展XSLT以匹配,但我相信您可以解决这个问题。