按年份和月份将新闻列表转换为HTML菜单分组

时间:2011-12-21 01:39:46

标签: html xml xslt xslt-1.0

目标是使用xslt 1.0输出<ul>删除按年份分组的重复月份。

这似乎与Grouping XML nodes by Month and Year in XSLT类似,但我不确定如何翻译以下标记的解决方案:

<news>
    <entry>
        <title>News Item 1</title>
        <meta>
            <year>2011</year>
            <month>12</month>
            <day>05</day>
        </meta>
    </entry>
    <entry>
        <title>News Item 2</title>
        <meta>
            <year>2011</year>
            <month>12</month>
            <day>09</day>
        </meta>
    </entry>
    <entry>
        <title>News Item 3</title>
        <meta>
            <year>2011</year>
            <month>11</month>
            <day>25</day>
        </meta>
    </entry>
    <entry>
        <title>News Item 4</title>
        <meta>
            <year>2011</year>
            <month>10</month>
            <day>16</day>
        </meta>
    </entry>
    <entry>
        <title>News Item 5</title>
        <meta>
            <year>2011</year>
            <month>12</month>
            <day>05</day>
        </meta>
    </entry>
    <entry>
        <title>News Item 6</title>
        <meta>
            <year>2010</year>
            <month>06</month>
            <day>13</day>
        </meta>
    </entry>
</news>

期望输出

<ul>
    <li>
        <a href="#">2011</a>
        <ul>
            <li>
                <a href="#">12</a>
            </li>
            <li>
                <a href="#">11</a>
            </li>
            <li>
                <a href="#">10</a>
            </li>
        </ul>
    </li>
    <li>
        <a href="#">2010</a>
        <ul>
            <li>
                <a href="#">06</a>
            </li>
        </ul>
    </li>
</ul>

1 个答案:

答案 0 :(得分:0)

此转化:

<xsl:stylesheet version="1.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="kEntryByYear" match="entry"
  use="meta/year"/>

 <xsl:key name="kMetaByYearMonth" match="meta"
  use="concat(year, '+', month)"/>

 <xsl:template match="/*">
  <ul>
    <xsl:apply-templates select=
     "entry
        [generate-id()
        =
         generate-id(key('kEntryByYear',
                          meta/year
                         )[1]
                     )
         ]
      ">
       <xsl:sort select="meta/year" data-type="number"
        order="descending"/>
     </xsl:apply-templates>
  </ul>
 </xsl:template>

 <xsl:template match="entry">
  <li>
   <a href="#"><xsl:value-of select="meta/year"/></a>
   <ul>
     <xsl:apply-templates select=
          "key('kEntryByYear', meta/year)/meta
             [generate-id()
             =
              generate-id(key('kMetaByYearMonth',
                              concat(year, '+', month)
                              )[1]
                          )
             ]
          ">
      <xsl:sort select="month"
           data-type="number" order="descending"/>
     </xsl:apply-templates>
   </ul>
  </li>
 </xsl:template>

 <xsl:template match="meta">
  <li>
    <a href="#"><xsl:value-of select="month"/></a>
  </li>
 </xsl:template>
</xsl:stylesheet>

应用于提供的XML文档

<news>
    <entry>
        <title>News Item 1</title>
        <meta>
            <year>2011</year>
            <month>12</month>
            <day>05</day>
        </meta>
    </entry>
    <entry>
        <title>News Item 2</title>
        <meta>
            <year>2011</year>
            <month>12</month>
            <day>09</day>
        </meta>
    </entry>
    <entry>
        <title>News Item 3</title>
        <meta>
            <year>2011</year>
            <month>11</month>
            <day>25</day>
        </meta>
    </entry>
    <entry>
        <title>News Item 4</title>
        <meta>
            <year>2011</year>
            <month>10</month>
            <day>16</day>
        </meta>
    </entry>
    <entry>
        <title>News Item 5</title>
        <meta>
            <year>2011</year>
            <month>12</month>
            <day>05</day>
        </meta>
    </entry>
    <entry>
        <title>News Item 6</title>
        <meta>
            <year>2010</year>
            <month>06</month>
            <day>13</day>
        </meta>
    </entry>
</news>

生成想要的正确结果

<ul>
   <li>
      <a href="#">2011</a>
      <ul>
         <li>
            <a href="#">12</a>
         </li>
         <li>
            <a href="#">11</a>
         </li>
         <li>
            <a href="#">10</a>
         </li>
      </ul>
   </li>
   <li>
      <a href="#">2010</a>
      <ul>
         <li>
            <a href="#">06</a>
         </li>
      </ul>
   </li>
</ul>

<强>解释

  1. Muenchian将entry分组为一个键(meta/year)。

  2. Muenchian通过复合键对meta进行分组,具体取决于yearmonth