3

我在为以下转换创建 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>
4

1 回答 1

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 以匹配,但我相信您可以解决这个问题。

于 2013-03-17T18:06:21.700 回答