将 xsl:number 与 xsl:for-each-group 一起使用

Use xsl:number together with xsl:for-each-group

考虑以下 XML 文档:

<cities>
    <city name="Milano"  country="Italia"      pop="5"/>
    <city name="Paris"   country="France"      pop="7"/>
    <city name="München" country="Deutschland" pop="4"/>
    <city name="Lyon"    country="France"      pop="2"/>
    <city name="Venezia" country="Italia"      pop="1"/>
 </cities>

使用上面的 XML 文档和 XSLT,我想获得以下输出(期望的输出):

1.Country: Italia:
       1.1. City: Milano   
       Population: 5 Millions
       1.2. City: Venezia   
        Population: 1 Millions
       total Population: 6 Millions

    2.Country: France:
       2.1. City: Paris   
       Population: 7 Millions
       2.2 City: Lyon   
       Population: 2 Millions
       total Population: 9 Millions

    3.Country: Deutschland:
       3.1 City: München   
        Population: 4 Millions
        total Population: 4 Millions

这是我的尝试(它没有给我想要的):

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
        version="2.0">
    <xsl:template match="cities">
        <xsl:for-each-group select="city" group-by="@country">
            <xsl:number format="1."/>Country: <xsl:value-of select="current-grouping-key()"/>:
            <xsl:for-each select="current-group()">
            <!--<xsl:number count="current-group()|@name" format="1.1." level="multiple"/>: Error The current-group() function cannot be used in a pattern -->
            City: <xsl:value-of select="@name" />   
            Population: <xsl:value-of select="@pop"/> Millions</xsl:for-each>
            total Population: <xsl:value-of select="sum(current-group()/@pop)"/> Millions
        </xsl:for-each-group>
    </xsl:template> 
</xsl:stylesheet>

xsl:number 您尝试的方式主要有助于根据输入结构进行编号,但也许以下就足够了:

 <xsl:template match="cities">
        <xsl:for-each-group select="city" group-by="@country">
            <xsl:number format="1." value="position()"/>Country: <xsl:value-of select="current-grouping-key()"/>:
            <xsl:variable name="group-pos" select="position()"/>
            <xsl:for-each select="current-group()">
              
            <xsl:number value="$group-pos, position()" format="1.1." />: City: <xsl:value-of select="@name" />   
            Population: <xsl:value-of select="@pop"/> Millions
             </xsl:for-each>
            total Population: <xsl:value-of select="sum(current-group()/@pop)"/> Millions
        </xsl:for-each-group>
    </xsl:template> 

根据结果格式(如 HTML),构建嵌套的 ol/li 列表并让它们成为 numbered/styled 和 CSS 可能更容易。

或者首先为您拥有的 xsl:numbering 创建一个临时 country/city 层次结构:

 <xsl:template match="cities">
    <xsl:variable name="countries">
      <xsl:for-each-group select="city" group-by="@country">
        <country name="{current-grouping-key()}" pop="{sum(current-group()/@pop)}">
          <xsl:copy-of select="current-group()"/>
        </country>
      </xsl:for-each-group>
    </xsl:variable>
    <xsl:for-each select="$countries/country">
        <xsl:number format="1."/>Country: <xsl:value-of select="@name"/>:
            <xsl:for-each select="city">
              
            <xsl:number level="multiple" format="1.1." count="country | city"/>: City: <xsl:value-of select="@name" />   
            Population: <xsl:value-of select="@pop"/> Millions
            </xsl:for-each>
        total Population: <xsl:value-of select="@pop"/> Millions
    </xsl:for-each>
  </xsl:template>