gpt4 book ai didi

XSLT,按年份日期排序和分组

转载 作者:行者123 更新时间:2023-12-02 09:00:17 25 4
gpt4 key购买 nike

关于 Umbraco XSLT 版本 1。

我有大约。 XML 格式的 150 条新闻。让我们这样说(在我更熟悉这个 xml/xslt 之前,所有都是伪代码):

<news>
<data alias=date>2008-10-20</data>
</news>
<news>
<data alias=date>2009-11-25</data>
</news><news>
<data alias=date>2009-11-20</data>
</news> etc. etc....

我想运行 XML 并创建 html 输出作为新闻存档。像这样的东西(标签不重要):

2008
Jan
Feb
...
2009
Jan
Feb
Mar
etc. etc.

我只能想出一个嵌套的 for-each (伪代码):

var year_counter = 2002
var month_counter = 1
<xsl:for-each select="./data [@alias = 'date']=year_counter">
<xsl:for-each select="./data [@alias = 'date']=month_counter">
<xsl:value-of select="data [@alias = 'date']>
"...if month_counter==12 end, else month_counter++ ..."
</xsl:for-each>
"... year_counter ++ ..."
</xsl:for-each>

但是一位程序员指出,循环 10 年将产生 120 次循环,这是糟糕的编码。因为我认为 Umbraco 缓存了结果,所以我不太关心,而且在这种情况下会有一个最大值。共 150 条记录。

关于如何排序和输出许多新闻项目并将其按年份分组以及每年按月份分组的任何线索?

兄弟。安德斯

最佳答案

对于以下解决方案,我使用了此 XML 文件:

<root>
<news>
<data alias="date">2008-10-20</data>
</news>
<news>
<data alias="date">2009-11-25</data>
</news>
<news>
<data alias="date">2009-11-20</data>
</news>
<news>
<data alias="date">2009-03-20</data>
</news>
<news>
<data alias="date">2008-01-20</data>
</news>
</root>

以及这个 XSLT 1.0 转换:

<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="xml" encoding="utf-8" />

<!-- index news by their "yyyy" value (first 4 chars) -->
<xsl:key
name="kNewsByY"
match="news"
use="substring(data[@alias='date'], 1, 4)"
/>
<!-- index news by their "yyyy-mm" value (first 7 chars) -->
<xsl:key
name="kNewsByYM"
match="news"
use="substring(data[@alias='date'], 1, 7)"
/>

<!-- translation table (month number to name) -->
<config xmlns="http://tempuri.org/config">
<months>
<month id="01" name="Jan" />
<month id="02" name="Feb" />
<month id="03" name="Mar" />
<month id="04" name="Apr" />
<month id="05" name="May" />
<month id="06" name="Jun" />
<month id="07" name="Jul" />
<month id="08" name="Aug" />
<month id="09" name="Sep" />
<month id="10" name="Oct" />
<month id="11" name="Nov" />
<month id="12" name="Dec" />
</months>
</config>

<xsl:template match="root">
<xsl:copy>
<!-- group news by "yyyy" -->
<xsl:apply-templates mode="year" select="
news[
generate-id()
=
generate-id(key('kNewsByY', substring(data[@alias='date'], 1, 4))[1])
]
">
<xsl:sort select="data[@alias='date']" order="descending" />
</xsl:apply-templates>
</xsl:copy>
</xsl:template>

<!-- year groups will be enclosed in a <year> element -->
<xsl:template match="news" mode="year">
<xsl:variable name="y" select="substring(data[@alias='date'], 1, 4)" />
<year num="{$y}">
<!-- group this year's news by "yyyy-mm" -->
<xsl:apply-templates mode="month" select="
key('kNewsByY', $y)[
generate-id()
=
generate-id(key('kNewsByYM', substring(data[@alias='date'], 1, 7))[1])
]
">
<xsl:sort select="data[@alias='date']" order="descending" />
</xsl:apply-templates>
</year>
</xsl:template>

<!-- month groups will be enclosed in a <month> element -->
<xsl:template match="news" mode="month">
<xsl:variable name="ym" select="substring(data[@alias='date'], 1, 7)" />
<xsl:variable name="m" select="substring-after($ym, '-')" />
<!-- select the label of the current month from the config -->
<xsl:variable name="label" select="document('')/*/cfg:config/cfg:months/cfg:month[@id = $m]/@name" />
<month num="{$m}" label="{$label}">
<!-- process news of the current "yyyy-mm" group -->
<xsl:apply-templates select="key('kNewsByYM', $ym)">
<xsl:sort select="data[@alias='date']" order="descending" />
</xsl:apply-templates>
</month>
</xsl:template>

<!-- for the sake of this example, news elements will just be copied -->
<xsl:template match="news">
<xsl:copy-of select="." />
</xsl:template>
</xsl:stylesheet>

应用转换后,会产生以下输出:

<root>
<year num="2009">
<month num="11" label="Nov">
<news>
<data alias="date">2009-11-25</data>
</news>
<news>
<data alias="date">2009-11-20</data>
</news>
</month>
<month num="03" label="Mar">
<news>
<data alias="date">2009-03-20</data>
</news>
</month>
</year>
<year num="2008">
<month num="10" label="Oct">
<news>
<data alias="date">2008-10-20</data>
</news>
</month>
<month num="01" label="Jan">
<news>
<data alias="date">2008-01-20</data>
</news>
</month>
</year>
</root>

它已经具有正确的结构,您可以根据自己的需要调整实际外观。

解决方案是两阶段 Muenchian 分组方法。第一阶段新闻按年份分组,第二阶段按年月分组。

请引用我对<xsl:key>的解释和key() over here 。您不需要阅读另一个问题,尽管它是一个类似的问题。请阅读我答案的下半部分。

关于XSLT,按年份日期排序和分组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1770383/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com