在XSLT 1.0中格式化24小时时间的最佳方法是什么?
我一直很难找到采用时间格式并轻松确定其是否有效的好方法,然后使用XSLT 1.0生成具有某种格式的结果元素。
给定以下xml:
<root> <srcTime>2300</srcTime> </root>
产生生成的xml会很棒:
<root> <dstTime>23:00</dstTime> </root>
但是,如果源xml包含无效的24小时制,则结果dstTime元素应为空白。
例如,当无效的源xml是以下内容时:
<root> <srcTime>NOON</srcTime> </root>
生成的xml应该是:
<root> <dstTime></dstTime> </root>
问题是,可以编写出最佳结果的最佳XSLT 1.0片段是什么?希望可以使其保持非常简单,而不必每次都解析(例如,如果可能的话,模式匹配会很不错)。
解决方案
XSLT 1.0没有对日期/时间操作的任何标准支持。
我们必须编写一个简单的解析和格式化功能。这将不会很简单,也不会变得很漂亮。
XSLT实际上是为树转换而设计的。最好在XSLT之外完成这种文本节点操作。
看一下:
http://www.exslt.org/特别是"日期和时间"部分。
我没有深入研究它,但是看起来它可能正是我们想要的。
甚至exslt.org time()函数也无法为我们提供帮助,因为它希望输入的格式正确(xs:dateTime或者xs:time)。
这是最好在XSLT之外解决的问题。我说这是一个经常使用XSLT来做并非真正为之设计的事情并且设法使事情起作用的人。它实际上并非旨在分析字符串。
理想的解决方案是修复生成XML文档的所有内容,以便使用为此目的而方便地建立的国际标准来格式化时间,并应遵循以下原则:如果可以避免的话,则不应该保留或者传输废话数据。
但是,如果那不可能,则应该在将数据传递给XSLT之前对其进行修复,或者在生成转换的输出之后对其进行修复。
XSLT 1.0中没有任何正则表达式,因此,恐怕模式匹配将无法实现。
我不清楚<srcTime> 23:00 </ srcTime>
是否合法?如果是这样,请尝试:
<dstTime> <xsl:if test="string-length(srcTime) = 4 or string-length(srcTime) = 5"> <xsl:variable name="hour" select="substring(srcTime, 1, 2)" /> <xsl:if test="$hour >= 0 and 24 > $hour"> <xsl:variable name="minute"> <xsl:choose> <xsl:when test="string-length(srcTime) = 5 and substring(srcTime, 3, 1) = ':'"> <xsl:value-of select="substring(srcTime, 4, 2)" /> </xsl:when> <xsl:when test="string-length(srcTime) = 4"> <xsl:value-of select="substring(srcTime, 3, 2)" /> </xsl:when> </xsl:choose> </xsl:variable> <xsl:if test="$minute >= 0 and 60 > $minute"> <xsl:value-of select="concat($hour, ':', $minute)" /> </xsl:if> </xsl:if> </xsl:if> </dstTime>
如果不是,那么只有四位数是合法的,那么:
<dstTime> <xsl:if test="string-length(srcTime) = 4"> <xsl:variable name="hour" select="substring(srcTime, 1, 2)" /> <xsl:if test="$hour >= 0 and 24 > $hour"> <xsl:variable name="minute" select="substring(srcTime, 3, 2)" /> <xsl:if test="$minute >= 0 and 60 > $minute"> <xsl:value-of select="concat($hour, ':', $minute)" /> </xsl:if> </xsl:if> </xsl:if> </dstTime>
根据实际使用的xslt处理器,我们可以在自定义扩展功能中进行所需的操作(我们必须自己做)。
Xalan对扩展功能有很好的支持,我们不仅可以用Java编写它们,还可以用JavaScript或者Apache BSF支持的其他语言编写它们。
Microsoft的XSLT引擎也支持自定义扩展,如.NET Framework开发人员指南,扩展XSLT样式表中所述
为了使列表完整,Steve Ball还提供了XSLT标准库的日期/时间处理模块部分。