【发布时间】:2015-10-02 07:31:28
【问题描述】:
我有一个 Joomla SobiPro 事件数据库,每个事件都包含一个名为“start_date”的日期字段,看起来像“2015 年 10 月 10 日”和“2016 年 1 月 3 日”。我需要搜索不同的字段(与给定邮政编码的距离(以英里为单位)),然后输出按这些日期升序排序的结果。
我对 XSL/SobiPro/Joomla 完全陌生,所以我很挣扎,但经过大量谷歌搜索后,我发现我需要在 SobiPro 模板中<!-- **** Insert Sort Command Here **** --> 指示的位置插入 XSL 排序命令文件 common/entries.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"><div class="row-fluid" ></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"></div></xsl:text>
</xsl:if>
</xsl:for-each>
</div>
<xsl:comment>entries loop - end</xsl:comment>
</xsl:template>
</xsl:stylesheet>
我对 XSL 完全不熟悉,但我确实发现如果日期格式是 2015 10 09 而不是 Oct 09 2015,那么我可以将上面的注释行替换为以下行:
<xsl:sort select="fields/field_start_date" order="ascending" />
并且排序会成功,因为它似乎是按字母顺序排序的。我无法更改日期格式,也无法以该可排序格式添加与日期相同的第二个字段。
我还发现,如果我按原样保留日期格式,我可以按年份排序,然后按月份名称排序:
<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" />
但这不会产生所需的升序日期输出顺序,因为二月按字母顺序排在一月之前,等等。
我知道从日期末尾向后计数字符以查找每个数据组件(年、日和月)的开始看起来很奇怪,但我尝试从零和 1 向前计数,但无法做到工作。似乎月份名称从字符位置 9 开始(idk 为什么 - 关于 start_date 是一个带有字符串 + 时区 + 我期望的其他信息的复合字段)但是日期编号不像你所期望的那样从位置 13 开始我放弃了尝试通过反复试验来找到它。
鉴于上述情况,尽管我仍然需要弄清楚如何将月份名称缩写映射到数字(Jan->01、Feb->02 等),并且我找到了各种方法示例,例如@DimitreNovaatchev 的https://stackoverflow.com/a/555536/1745001,但经过一天的研究和反复试验,我无法弄清楚如何重新排列该代码或任何其他类似代码以适应我现有的 XSL 文件并在我的情况下工作。
谁能帮我解决这个问题?
上下文:
如果您访问了我的网站 http://tournamart.com/,请向下滚动到地图下方,然后在给定字段中输入这些值:
Distance From: [Oswego, Illinois, USA] [(Drop Down:) 100 miles]
Start Date
From: [10/01/2015]
To: [03/01/2015]
然后单击绿色的“开始搜索”按钮,该网站将打印 2015 年 10 月 1 日至 2016 年 3 月 1 日期间奥斯威戈 100 英里范围内即将举行的 9 场锦标赛的列表。我试图让输出按日期排序,以便最早的比赛排在第一位。在不修改代码的情况下,据我所知,输出是按照在数据库中输入的顺序排列的。
鉴于以下建议的解决方案 (https://stackoverflow.com/a/32904143/1745001):
<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" />
它似乎成功了,因为它现在生成了:
Glen Ellyn Lakers FC 2015 Fall Classic
City: Glen Ellyn
State: Illinois
Start Date: Oct 02 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
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
Winter Freeze
City: Crown Point
State: Indiana
Start Date: Dec 04 2015
PUMA 2016 MARTIN LUTHER KING INDOOR CUP
City: Sturtevant
State: Wisconsin
Start Date: Jan 15 2016
PUMA 2016 PRESIDENTS DAY INDOOR CUP
City: Sturtevant
State: Wisconsin
Start Date: Feb 13 2016
所以,这非常有帮助,谢谢,剩下的问题是:
- 为什么我必须从末尾倒数 char 位置?
- 是否有更有效(或稳健或“更好”)的方法来做到这一点?
【问题讨论】:
-
这是 XSLT 1.0 还是 2.0? XSLT 2.0 在这方面要好得多,但是很多开源产品都停留在 XSLT 1.0 上。
-
我不知道,但上面代码的第一行写着
version="1.0",这是否意味着它是 XSLT 1.0? -
重要的是处理器能做什么,而不是样式表说什么。在这里查看如何找到:stackoverflow.com/questions/25244370/…
-
好的,我查看了该参考资料并看到了一行代码。我是否将其添加到我正在编辑的文件中的某个位置?如果是在哪里?如果不是,我该怎么办?完成后我应该期待看到什么?同样,我在这个领域或使用 XLS 方面的经验绝对为零。
-
使用这个样式表代替你的:pastebin.com/gGChraNG
标签: xslt