【问题标题】:xsl muenchian grouping multiple levelsxsl muenchian 分组多个级别
【发布时间】:2013-12-06 12:07:00
【问题描述】:

我一直在尝试学习使用其他帖子来理解 muenchian 分组,但我正在努力将正确的分组转换为表格格式。分组需要分为两个级别,首先是赛季“年”,然后是每个赛季显示按“组”分组的匹配项。我已经设法将“组”分组,但它们都显示在最新一季,而不是分成各自的季节。这是xml的一个例子:

<DocumentElement>
  <QueryResults>
    <Years>2013/2014</Years>
    <Group>1</Group>
    <TeamNameShort>TeamA</TeamNameShort>
  </QueryResults>
  <QueryResults>
    <Years>2013/2014</Years>
    <Group>1</Group>
    <TeamNameShort>TeamB</TeamNameShort> 
  </QueryResults>
  <QueryResults>
    <Years>2013/2014</Years>
    <Group>2</Group>
    <TeamNameShort>TeamC</TeamNameShort>
</QueryResults>
<QueryResults>
    <Years>2013/2014</Years>
    <Group>2</Group>
    <TeamNameShort>TeamD</TeamNameShort>
</QueryResults>
 <QueryResults>
    <Years>2012/2013</Years>
    <Group>1</Group>
    <TeamNameShort>TeamA</TeamNameShort>
</QueryResults>
<QueryResults>
    <Years>2012/2013</Years>
    <Group>1</Group>
    <TeamNameShort>TeamB</TeamNameShort>
  </QueryResults>
  <QueryResults>
    <Years>2012/2013</Years>
    <Group>2</Group>
    <TeamNameShort>TeamC</TeamNameShort>
  </QueryResults>
  <QueryResults>
  <Years>2012/2013</Years>
  <Group>2</Group>
  <TeamNameShort>TeamD</TeamNameShort>
  </QueryResults>
</DocumentElement>

xsl 目前看起来像这样

<xsl:stylesheet 
version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:cfg="http://tempuri.org/config"
exclude-result-prefixes="cfg"
> 

<xsl:output method="html" indent="yes"/>

<!-- index by season -->
<xsl:key 
name="Season"  
match="QueryResults" 
use="Years" 
/>

<!-- index by "Pool"  -->
<xsl:key 
name="Pool" 
match="QueryResults" 
use="Group" 
/>

<xsl:template match="DocumentElement">
  <xsl:copy>
    <!-- group by season -->
    <xsl:apply-templates mode="season" select="
    QueryResults[
      generate-id()
      =
      generate-id(key('Season', Years)[1])
    ]
  ">
    <xsl:sort select="Years" order="descending" />
  </xsl:apply-templates>
</xsl:copy>
</xsl:template>

<!-- Season -->
<xsl:template match="QueryResults" mode="season">
<xsl:variable name="y" select="Years" />
  <table>
    <tbody>   
    <tr>
      <td colspan="3">Season <xsl:value-of select="$y"/></td>
    </tr>
    <tr>
        <th>Pos</th>
        <th>Group/Year</th>
        <th>Team</th>
    </tr>

<!-- group Season by Pool -->
<xsl:apply-templates mode="pool" select="
    key('Season', $y)[
      generate-id() 
      =
      generate-id(key('Pool',Group)[1])
    ]
  ">
</xsl:apply-templates>
</tbody>
</table>
</xsl:template>

<!-- Pool -->
<xsl:template match="QueryResults" mode="pool">
<xsl:variable name="g" select="Group" />

  <tr>
    <td colspan="3">Pool <xsl:value-of select="Group"/></td>
  </tr>

    <xsl:for-each select="key('Pool',$g)"> 
    <tr>
     <td><xsl:value-of select="Group"/></td>
     <td><xsl:value-of select="Years"/></td>
     <td><xsl:value-of select="TeamNameShort"/></td>
    </tr>
 </xsl:for-each>
</xsl:template>

  <xsl:template match="QueryResults">
<xsl:copy-of select="." />
</xsl:template>

</xsl:stylesheet>

【问题讨论】:

    标签: xml xslt muenchian-grouping


    【解决方案1】:

    问题在于,您不应该仅按 Group 元素进行分组,而应按给定 YearGroup 进行分组。实际上,您需要使用连接键

    <xsl:key name="Pool" match="QueryResults" use="concat(Years, '|', Group)"/>
    

    那么,只要您引用键,就可以简单地使用此连接值。例如

    <xsl:apply-templates mode="pool" select="
       key('Season', $y)
          [
             generate-id() = generate-id(key('Pool',concat(Years, '|', Group))[1])
          ]"/>
    

    请注意,这里的 | 字符实际上可以是任何字符,只要它没有出现在您要连接的两个值中的任何一个中即可。

    试试这个 XSLT

    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:cfg="http://tempuri.org/config" exclude-result-prefixes="cfg">
       <xsl:output method="html" indent="yes"/><!-- index by season -->
       <xsl:key name="Season" match="QueryResults" use="Years"/><!-- index by "Pool"  -->
       <xsl:key name="Pool" match="QueryResults" use="concat(Years, '|', Group)"/>
    
       <xsl:template match="DocumentElement">
          <xsl:copy><!-- group by season -->
              <xsl:apply-templates mode="season" select="QueryResults[generate-id() = generate-id(key('Season', Years)[1])]">
                <xsl:sort select="Years" order="descending"/>
             </xsl:apply-templates>
          </xsl:copy>
       </xsl:template><!-- Season -->
       <xsl:template match="QueryResults" mode="season">
    
          <xsl:variable name="y" select="Years"/>
          <table>
             <tbody>
                <tr>
                   <td colspan="3">Season 
                      <xsl:value-of select="$y"/></td>
                </tr>
                <tr>
                   <th>Pos</th>
                   <th>Group/Year</th>
                   <th>Team</th>
                </tr><!-- group Season by Pool -->
                <xsl:apply-templates mode="pool" select="key('Season', $y)[generate-id()  = generate-id(key('Pool',concat(Years, '|', Group))[1])]"/>
             </tbody>
          </table>
       </xsl:template>
    
       <!-- Pool -->
       <xsl:template match="QueryResults" mode="pool">
          <xsl:variable name="g" select="concat(Years, '|', Group)"/>
          <tr>
             <td colspan="3">Pool 
                <xsl:value-of select="Group"/></td>
          </tr>
          <xsl:for-each select="key('Pool',$g)">
             <tr>
                <td>
                   <xsl:value-of select="Group"/>
                </td>
                <td>
                   <xsl:value-of select="Years"/>
                </td>
                <td>
                   <xsl:value-of select="TeamNameShort"/>
                </td>
             </tr>
          </xsl:for-each>
       </xsl:template>
    
       <xsl:template match="QueryResults">
          <xsl:copy-of select="."/>
       </xsl:template>
    </xsl:stylesheet>
    

    【讨论】:

    • 这很有意义,很好的解决方案 - 谢谢!
    • 这是一个优雅的解决方案,写得很好。干得好!
    猜你喜欢
    • 2018-10-20
    • 2017-07-12
    • 2012-07-07
    • 2016-08-19
    • 2016-05-19
    • 1970-01-01
    • 2021-11-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多