按月 - 名称日 - 数字年 - 数字格式按日期对XSL进行排序

时间:2015-10-02 07:31:29

标签: xslt

我有一个Joomla SobiPro事件数据库,每个事件都包含一个名为" start_date"的日期字段。看起来像" 2015年10月10日"和" 2016年1月3日"。我需要搜索不同的字段(距离给定的邮政编码的距离为英里),然后按升序排列按日期排序的结果。

我对XSL / SobiPro / Joomla来说是全新的,所以我很挣扎,但经过大量的谷歌搜索后,我发现我需要在{{1}下面指示的位置插入一个XSL排序命令在SobiPro模板文件common / entries.xsl:

<!-- **** Insert Sort Command Here **** -->

我根本不熟悉XSL,但我确实发现如果日期格式为<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="xml" doctype-system="http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd" encoding="UTF-8" /> <xsl:include href="vcard.xsl" /> <xsl:include href="manage.xsl" /> <xsl:template name="entriesLoop"> <xsl:variable name="entriesInLine"> <xsl:value-of select="entries_in_line" /> </xsl:variable> <xsl:variable name="cellClass"> <xsl:value-of select="floor( 12 div $entriesInLine )" /> </xsl:variable> <xsl:variable name="entriesCount"> <xsl:value-of select="count(entries/entry)" /> </xsl:variable> <xsl:comment>entries loop - start</xsl:comment> <div class="entry-container"> <xsl:for-each select="entries/entry"> <!-- **** Insert Sort Command Here **** --> <xsl:if test="($entriesInLine > 1 and (position() = 1 or (position() mod $entriesInLine) = 1 )) or $entriesInLine = 1"> <!-- opening the "table" row --> <xsl:text disable-output-escaping="yes">&lt;div class="row-fluid" &gt;</xsl:text> </xsl:if> <div class="span{$cellClass}"> <xsl:call-template name="vcard" /> </div> <xsl:if test="($entriesInLine > 1 and ((position() mod $entriesInLine) = 0 or position() = $entriesCount)) or $entriesInLine = 1"> <!-- closing the "table" row --> <xsl:text disable-output-escaping="yes">&lt;/div&gt;</xsl:text> </xsl:if> </xsl:for-each> </div> <xsl:comment>entries loop - end</xsl:comment> </xsl:template> </xsl:stylesheet> 而不是2015 10 09,那么我可以用这一行替换上面的注释行:

Oct 09 2015

并且排序会成功,因为它似乎按字母顺序排序。我无法更改日期格式,也无法在该可排序格式中添加第二个相同日期的字段。

我还发现,如果我按原样保留日期格式,我可以按年份排序,然后按月份名称排序:

<xsl:sort select="fields/field_start_date" order="ascending" />

但不会产生所需的提升日期输出顺序,因为2月按字母顺序排在Jan之前等等。

我知道从日期结束开始计算字符以查找每个数据组件的开头(年,日和月)看起来很奇怪但是我尝试从0和1向前计数并且无法进行计数工作。看起来月份名称从字符位置9开始(idk为什么 - 关于start_date是一个复合字段,字符串+时区+我期望的其他信息)然后日期编号不会从第13位开始,因为你&# 39; d期待,我放弃了试图通过反复试验找到它。

鉴于上述情况,我仍然需要弄清楚如何将月份名称缩写映射到数字(Jan-> 01,Feb-> 02等),并且我找到了各种方法的例子这样做,例如https://stackoverflow.com/a/555536/1745001来自@DimitreNovatchev,但经过一天的研究和反复试验后,我无法弄清楚如何重新安排该代码或任何其他类似的代码以适应我现有的XSL文件并在我的工作中工作情况下。

任何人都可以帮我解决这个问题吗?

上下文:

如果您到达我的网站http://tournamart.com/,请在地图下方向下滚动,然后在给定字段中输入这些值:

<xsl:sort select="concat(
        substring(fields/field_start_date,string-length(fields/field_start_date)-3,4),
        substring(fields/field_start_date,string-length(fields/field_start_date)-10,3),
        substring(fields/field_start_date,string-length(fields/field_start_date)-6,2)
                         )" order="ascending" />

然后点击绿色&#34;开始搜索&#34;按钮,该网站将打印2015年10月1日至2016年3月1日在奥斯威戈100英里范围内举行的9场比赛的列表。我试图按日期排序输出,以便最早的锦标赛排在第一位。在没有修改代码的情况下,输出,我能说的最好是按照在数据库中输入的顺序排序。

鉴于下面提出的解决方案(https://stackoverflow.com/a/32904143/1745001):

Distance From: [Oswego, Illinois, USA]  [(Drop Down:) 100 miles]
Start Date
    From: [10/01/2015]
    To:   [03/01/2015]

输出仍未按日期排序:

<xsl:sort select="substring(fields/field_start_date, 8 , 4)" data-type="number" />
<xsl:sort select="string-length(substring-before('JanFebMarAprMayJunJulAugSepOctNovDec', substring(fields/field_start_date, 1 , 3)))" data-type="number" />
<xsl:sort select="substring(fields/field_start_date, 5 , 2)" data-type="number" />

但是当我修改代码以从日期字符串的末尾开始计算字符时:

PUMA 2016 PRESIDENTS DAY INDOOR CUP
City: Sturtevant
State: Wisconsin
Start Date: Feb 13 2016

PUMA 2016 MARTIN LUTHER KING INDOOR CUP
City: Sturtevant
State: Wisconsin
Start Date: Jan 15 2016

Winter Freeze
City: Crown Point
State: Indiana
Start Date: Dec 04 2015

2015 Eclipse Select AT&T Oktoberfest Shootout
City: Waukegan
State: Illinois
Start Date: Oct 10 2015

Racine Lighthouse Classic - 2015
City: Franksville
State: Wisconsin
Start Date: Oct 10 2015

Sockers Nike Classic Cup Fall 2015
City: Chicago
State: Illinois
Start Date: Oct 09 2015

2015 Octoberfest Classic Presented by Quaker Oats
City: Libertyville
State: Illinois
Start Date: Oct 09 2015

WSA Columbus Day Classic
City: Wheeling
State: Illinois
Start Date: Oct 09 2015

Glen Ellyn Lakers FC 2015 Fall Classic
City: Glen Ellyn
State: Illinois
Start Date: Oct 02 2015

它似乎成功,因为它现在生成:

<xsl:sort select="substring(fields/field_start_date, string-length(fields/field_start_date)-3 , 4)" data-type="number" />
<xsl:sort select="string-length(substring-before('JanFebMarAprMayJunJulAugSepOctNovDec', substring(fields/field_start_date, string-length(fields/field_start_date)-10 , 3)))" data-type="number" />
<xsl:sort select="substring(fields/field_start_date, string-length(fields/field_start_date)-6 , 2)" data-type="number" />

所以,这非常有帮助,谢谢,剩下的问题是:

  1. 为什么我必须从最后算起慈善职位?
  2. 是否有更高效(或更强大或更好的&#34;)方式来做到这一点?

1 个答案:

答案 0 :(得分:1)

  

我仍然需要弄清楚如何将月份名称缩写映射到   数字(Jan-> 01,Feb-> 02等)

你可以这样做:

string-length(substring-before('JanFebMarAprMayJunJulAugSepOctNovDec', substring($f, 1 , 3)))

这将缩写映射为Jan-> 0,Feb-> 3,Mar-> 6等,这对数字排序来说足够了。

我建议您只使用三个数字排序指令,而不是尝试制作单个文本字符串:

<xsl:sort select="substring(fields/field_start_date, 8 , 4)" data-type="number" />
<xsl:sort select="string-length(substring-before('JanFebMarAprMayJunJulAugSepOctNovDec', substring(fields/field_start_date, 1 , 3)))" data-type="number" />
<xsl:sort select="substring(fields/field_start_date, 5 , 2)" data-type="number" />
  

我知道从字母结尾回来计算字符看起来很奇怪   日期以查找每个数据组件的开头(年,日和月)   但我尝试从零和1向前计数,但无法做到   它有效。

如果它仍然不适合您,请发布失败的输入示例。