获取xsl 1.0仅显示列表中组中的第一个项目

时间:2011-07-12 01:16:23

标签: list xslt grouping

这是针对博客文章的类别索引 - 我只想使用xsl v1.0一次显示该类别。每个类别中都会有多个帖子。期望的结果是:

Cat Name 1
cat Name 2
Cat Name 3 

我假设对项目进行分组并且仅显示组中的第一个项目(使用猫名称作为键)将起作用,但Muenchian方法有点超出我的能力。因此,对Muenchian方法的简单方法或简单解释将是最受欢迎的。

xml

<Root>
<Schema>
<Field Type="Lookup" DisplayName="Category name" Required="FALSE" ShowField="Category_x0020_name" Name="Category_x0020_name"  Group="" />
<Field ReadOnly="TRUE" Type="Computed" Name="LinkTitle" DisplayName="Post number" />
</Schema>
<Data ItemCount="1">
<Row  Category_x0020_name=""  LinkTitle="" /> 
</Data>
</Root>

xsl:

 <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html" />      
  <xsl:template match="/">
   <table border="0" cellpadding="0" cellspacing="0">     
 <h3>Categories</h3>
 <xsl:for-each select="//Data/Row">
                <xsl:if test="./@Category_x0020_name !=''"> 
 <tr valign="top">         <td>               
 <a href="/cat{./@LinkTitle}.aspx">  
 <xsl:value-of select="./@Category_x0020_name" /></a></td> </tr>
 </xsl:if>
 </xsl:for-each>
 </table>
 </xsl:template> 
 </xsl:stylesheet> 

2 个答案:

答案 0 :(得分:4)

不要害怕Meunchian方法。使用一次,您就可以随时应用它。

  • 将所需数据收集到密钥
  • 使用类似
  • 的谓词将模板应用于只有一个具有相同键的节点

generate-id()=generate-id(key(...)[1])

使用Meunchian分组是您需要知道的。这里是为了帮助您入门:

<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="Cat" match="Data/Row" use="@Category_x0020_name"/>

    <xsl:template match="/*/Data">
        <xsl:apply-templates select="Row
            [generate-id()
            = generate-id(key('Cat',@Category_x0020_name)[1])]"/>
    </xsl:template>

    <xsl:template match="Row">
        <xsl:value-of select="concat(@Category_x0020_name,'&#xA;')"/>
    </xsl:template>

</xsl:stylesheet>

答案 1 :(得分:1)

由于您不需要列出每个类别的成员,并且假设您的数据集不是很大,因此性能不是一个重要因素,您可以放弃Muenchian分组以获得不那么优雅的东西。只需将<xsl:if test>更改为:

即可
        <xsl:if test="./@Category_x0020_name !='' and
             not(./@Category_x0020_name = preceding::Row/@Category_x0020_name)">

换句话说,只在第一次出现时输出类别名称。

顺便说一句,您可以删除XPath表达式开头出现的./。这是多余的。它意味着“从上下文节点开始”,但您已经从上下文节点开始了。如果你想留下它以便于阅读,那就没关系。

然后输入

<Root>...
   <Data ItemCount="1">
      <Row  Category_x0020_name="foo"  LinkTitle="Foo" /> 
      <Row  Category_x0020_name="bar"  LinkTitle="Bar" /> 
      <Row  Category_x0020_name="foo"  LinkTitle="Foo" /> 
   </Data>
</Root>

你得到这个输出:

<table border="0" cellpadding="0" cellspacing="0">
   <h3>Categories</h3>
   <tr valign="top">
      <td><a href="/catFoo.aspx">foo</a></td>
   </tr>
   <tr valign="top">
      <td><a href="/catBar.aspx">bar</a></td>
   </tr>
</table>