Преобразование списка новостей в HTML-меню с группировкой по году и месяцу - PullRequest
2 голосов
/ 21 декабря 2011

Цель состоит в том, чтобы вывести <ul>, удалив повторяющиеся месяцы, сгруппированные по годам, используя xslt 1.0.

Это похоже на Группирование узлов XML по месяцам и годам в 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 голосов
/ 21 декабря 2011

Это преобразование:

<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. мюнхенская группировка entry по одной клавише (meta/year).

  2. мюнхенская группировка meta по составному ключу, в зависимости от year и month.

...