我曾在这里看过各种各样的建议,但没有一个能真正解决我的问题。由于XML的来源,我可以收到以下三种格式的日期;
04-04-2014(DD-MM-YYYY)
04-Apr-2014(DD-MMM-YYYY)
2014-04-04(YYYY-MM-DD)我希望有一个函数或简单的命令,将所有这些(第三个除外,但能够识别第三个是正确的)转换为YYYY DD。
我现在有很长的时间/什么时候/什么时候做这件事,但是肯定有一个更简单的方法。我现在的XSLT做了以下工作;
<xsl:choose>
<xsl:when test="contains(date, 'Jan')">
<xsl:value-of select="concat(substring(date,6),'-01-',substring(date,1,2))" />
</xsl:when>
<xsl:when test="contains(date, 'Feb')">
<xsl:value-of select="concat(substring(date,6),'-02-',substring(date,1,2))" />
</xsl:when>
<xsl:when test="contains(date, 'Mar')">
<xsl:value-of select="concat(substring(date,6),'-03-',substring(date,1,2))" />
</xsl:when>
<xsl:when test="contains(date, 'Apr')">
<xsl:value-of select="concat(substring(date,6),'-04-',substring(date,1,2))" />
</xsl:when>
<xsl:when test="contains(date, 'May')">
<xsl:value-of select="concat(substring(date,6),'-05-',substring(date,1,2))" />
</xsl:when>
<xsl:when test="contains(date, 'Jun')">
<xsl:value-of select="concat(substring(date,6),'-06-',substring(date,1,2))" />
</xsl:when>
<xsl:when test="contains(date, 'Jul')">
<xsl:value-of select="concat(substring(date,6),'-07-',substring(date,1,2))" />
</xsl:when>
<xsl:when test="contains(date, 'Aug')">
<xsl:value-of select="concat(substring(date,6),'-08-',substring(date,1,2))" />
</xsl:when>
<xsl:when test="contains(date, 'Sep')">
<xsl:value-of select="concat(substring(date,6),'-09-',substring(date,1,2))" />
</xsl:when>
<xsl:when test="contains(date, 'Oct')">
<xsl:value-of select="concat(substring(date,6),'-10-',substring(date,1,2))" />
</xsl:when>
<xsl:when test="contains(date, 'Nov')">
<xsl:value-of select="concat(substring(date,6),'-11-',substring(date,1,2))" />
</xsl:when>
<xsl:when test="contains(date, 'Dec')">
<xsl:value-of select="concat(substring(date,6),'-12-',substring(date,1,2))" />
</xsl:when>
<xsl:when test="string-length($dateStart) = 2">
<xsl:value-of select="concat(substring(date,7),'-',substring(date,4,2),'-',substring(date,1,2))" />
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="date"/>
</xsl:otherwise>
</xsl:choose>因此,这将检查该日期是否包含任何一月、二月等月份,如果没有,则检查到-为止的第一个数字是否为2个字符(DD)和格式,其他明智的方法是假设它已经是YYYY DD,并按原样输出。
我尝试过- <xsl:value-of select = "format-dateTime(date, '[Y0001]-[MN]-[D01]')"/>,但是这抱怨日期年不够长(因为日期被当作日期时间处理,它应该是YYYY-MM-DD格式)。
感谢Ian下面的答案,我创建了下面的内容来处理更多的场景,并将输出组合在一起;
<xsl:variable name="months" select="('Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec')" />
<xsl:analyze-string select="date" flags="x"
regex="^(
(\d\d)-(\d\d)-(\d\d\d\d)
| (\d\d)-([A-Za-z]{{3}})-(\d\d\d\d)
| (\d\d\d\d)-(\d\d)-(\d\d)
| (\d\d\d\d)-([A-Za-z]{{3}})-(\d\d)
| (\d\d)([A-Za-z]{{3}})(\d\d\d\d)
| (\d\d\d\d)([A-Za-z]{{3}})(\d\d))$">
<xsl:matching-substring>
<xsl:value-of select="if (regex-group(4)) then concat(regex-group(4),'-',regex-group(3),'-',regex-group(2)) else ''"/>
<xsl:value-of select="if (regex-group(7)) then concat(regex-group(7),'-',format-number(index-of($months, regex-group(6)), '00'),'-',regex-group(5)) else ''"/>
<xsl:value-of select="if (regex-group(8)) then concat(regex-group(8),'-',regex-group(9),'-',regex-group(10)) else ''"/>
<xsl:value-of select="if (regex-group(11)) then concat(regex-group(11),'-',format-number(index-of($months, regex-group(12)), '00'),'-',regex-group(13)) else ''"/>
<xsl:value-of select="if (regex-group(16)) then concat(regex-group(16),'-',format-number(index-of($months, regex-group(15)), '00'),'-',regex-group(14)) else ''"/>
<xsl:value-of select="if (regex-group(17)) then concat(regex-group(17),'-',format-number(index-of($months, regex-group(18)), '00'),'-',regex-group(19)) else ''"/>
</xsl:matching-substring>
</xsl:analyze-string>发布于 2014-04-04 17:25:52
由于您引用的是format-dateTime,所以您必须在XSLT2.0中,所以可以使用正则表达式来处理它。如果你知道你总是有这三种形式中的一种,那么你可以使用analyze-string
<xsl:variable name="months" select="('Jan', 'Feb', 'Mar', 'Apr', ...)" />
<xsl:analyze-string select="date" flags="x"
regex="^(
(\d\d)-(\d\d)-(\d\d\d\d)
| (\d\d)-([A-Za-z]{{3}})-(\d\d\d\d)
| (\d\d\d\d)-(\d\d)-(\d\d))$">
<xsl:matching-substring>
<!-- year -->
<xsl:value-of select="regex-group(4)"/>
<xsl:value-of select="regex-group(7)"/>
<xsl:value-of select="regex-group(8)"/>
<xsl:text>-</xsl:text>
<!-- month -->
<xsl:value-of select="regex-group(3)"/>
<xsl:value-of select="if (regex-group(6))
then format-number(index-of($months, regex-group(6)), '00')
else ''"/>
<xsl:value-of select="regex-group(9)"/>
<xsl:text>-</xsl:text>
<!-- day -->
<xsl:value-of select="regex-group(2)"/>
<xsl:value-of select="regex-group(5)"/>
<xsl:value-of select="regex-group(10)"/>
</xsl:matching-substring>
</xsl:analyze-string>每个示例格式都将完全匹配模式中的三个替代方案之一,所有对非匹配替代方案的regex-group调用都将生成空字符串。
发布于 2014-04-05 15:43:52
即使在XSLT1.0中,如果您关注的是不同格式的结构,而不是它们的内容,那么问题就变得相当简单。
<xsl:template name="normalize-datestring">
<xsl:param name="datestring"/>
<xsl:choose>
<xsl:when test="string-length(substring-before($datestring, '-')) = 4">
<!-- this is YYYY-MM-DD; copy as is -->
<xsl:value-of select="$datestring" />
</xsl:when>
<xsl:when test="string-length($datestring) = 10">
<!-- this is DD-MM-YYYY; reorder -->
<xsl:value-of select="substring($datestring, 7, 4)" />
<xsl:text>-</xsl:text>
<xsl:value-of select="substring($datestring, 4, 2)" />
<xsl:text>-</xsl:text>
<xsl:value-of select="substring($datestring, 1, 2)" />
</xsl:when>
<xsl:otherwise>
<!-- this is DD-MMM-YYYY; reorder and calculate month number-->
<xsl:value-of select="substring($datestring, 8, 4)" />
<xsl:text>-</xsl:text>
<xsl:variable name="mmm" select="substring($datestring, 4, 3)" />
<xsl:variable name="m" select="string-length(substring-before('JanFebMarAprMayJunJulAugSepOctNovDec', $mmm)) div 3 + 1" />
<xsl:value-of select="format-number($m, '00')" />
<xsl:text>-</xsl:text>
<xsl:value-of select="substring($datestring, 1, 2)" />
</xsl:otherwise>
</xsl:choose>
</xsl:template>发布于 2014-04-05 13:58:44
下面是一个函数,将类似的正则表达式和月份序列用作另一个答案:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:f="function" exclude-result-prefixes="xs"
version="2.0">
<xsl:variable name="d1" select="'2014-04-04'"/>
<xsl:variable name="d2" select="'04-04-2014'"/>
<xsl:variable name="d3" select="'04-Apr-2014'"/>
<xsl:template match="/">
<xsl:value-of select="f:processDate($d2,'[Y0001]-[MN]-[D01]')"/>
</xsl:template>
<xsl:function name="f:processDate">
<xsl:param name="dateString"/>
<xsl:param name="datePattern"/>
<xsl:variable name="month"
select="('Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Okt','Nov','Dez')"/>
<xsl:choose>
<!-- this will work for d1 -->
<xsl:when test="$dateString castable as xs:date">
<xsl:value-of select="format-date( xs:date($dateString),$datePattern)"/>
</xsl:when>
<!-- d2 -->
<xsl:when test="matches($dateString,'^(\d\d-\d\d-\d\d\d\d)$')">
<xsl:variable name="d" select="substring($dateString,1,2)"/>
<xsl:variable name="m" select="substring($dateString,4,2)"/>
<xsl:variable name="y" select="substring($dateString,7,4)"/>
<xsl:value-of select="format-date( xs:date( string-join(($y, $m, $d), '-')), $datePattern )"
/>
</xsl:when>
<!-- d3 -->
<xsl:when test="some $i in $month satisfies matches($dateString,concat('^(\d\d-',$i,'-\d\d\d\d)$'))">
<xsl:variable name="d" select="substring($dateString,1,2)"/>
<xsl:variable name="m"
select="format-number(index-of($month,substring($dateString,4,3)),'00')"/>
<xsl:variable name="y" select="substring($dateString,8,4)"/>
<xsl:value-of select="format-date( xs:date( string-join(($y, $m, $d), '-')), $datePattern )"
/>
</xsl:when>
<xsl:otherwise>
<xsl:message>Unsupported dateString: <xsl:value-of select="$dateString"/></xsl:message>
<xsl:value-of select="$dateString"/>
</xsl:otherwise>
</xsl:choose>
</xsl:function>
</xsl:stylesheet>https://stackoverflow.com/questions/22868423
复制相似问题