XSLT日期格式化 [英] XSLT Date Formatting

查看:122
本文介绍了XSLT日期格式化的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经看过这里的各种建议,但没有一个真的帮助我的问题。
由于我的XML源自我可以接收以下三种格式的日期:

  04-04- 2014年(DD-MM-YYYY)
2014年4月04日(DD-MMM-YYYY)
2014-04-04(YYYY-MM-DD)

我想要一个功能或简单的命令,将更改所有这些(除了第三个,但能够认识到第三个是正确的)到YYYY-MM-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:否则>
< xsl:value-of select =date/>
< / xsl:否则>
< / xsl:choose>

所以这将检查日期是否包含JAN,Feb等任何月份,如果没有,检查第一个号码是否为2个字符(DD)和格式,否则它假定它是YYYY-MM-DD,并按原样输出。



我尝试过 - < xsl:value-of select =format-dateTime(date,'[Y0001] - [MN] - [D01]')/>
但是,这抱怨日期年份不够长(因为日期被视为日期时间,应该是格式为YYYY-MM-DD



感谢Ian roberts回答如下,我创建了下面来处理更多的场景并将输出组合在一起;

  < xsl:variable name =monthsselect =('Jan','Feb','Mar','Apr','May','Jun','Jul','Aug' 'Oct','Nov','Dec')/> 
< xsl:analyze-string select =dateflags =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 ($ month,regex-group(12)),'00'),' - ',regex-group(13))else''/>
< xsl:value-of select = (regex-group(16))then concat(regex-group(16),' - ',format-number(index-of($ months,regex-group(15)),'00'),' - 正则表达式组(14))else''/>
< xsl:value-of select =if(regex-group(17))then concat(regex-group(17),' - ' number(index-of($ months,regex-group(18)),'00'),' - ',regex-group(19))else''/>
< / xsl:matching-substring>
< / xsl:analyze-string>


解决方案

由于您引用格式-dateTime 你必须在XSLT 2.0中,所以你可以使用正则表达式来处理它。如果你知道你总是会有三种形式之一,那么你可以使用 analyze-string

 < xsl:variable name =monthsselect =('Jan','Feb','Mar','Apr',...)/> 

< xsl:analyze-string select =dateflags =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>

每个示例格式都将匹配模式中的三个备选方案之一, code> regex-group 调用不匹配的替代项将产生空字符串。


I have had a look at various suggestions on here but none really help my problem. Due to the sources my XML comes from i can receive dates in the following three formats;

04-04-2014(DD-MM-YYYY)
04-Apr-2014(DD-MMM-YYYY)
2014-04-04(YYYY-MM-DD)

I would like to have a function or simple command that will change all of these (other than the third, yet able to recognize that the third is correct) into YYYY-MM-DD

I have a long winded When/when/when to do this currently, but there must be an easier way. My current XSLT does the following;

<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>

So this will check if the date contains any months as JAN,Feb etc. and then if not, check if the first number up to - is 2 characters (DD) and format, other wise it assumes it is YYYY-MM-DD already and outputs it as it is.

I have tried - <xsl:value-of select = "format-dateTime(date, '[Y0001]-[MN]-[D01]')"/> But this complains that the Dates year is not long enough (as date is being treated as a datetime, which should be in format YYYY-MM-DD

Thanks to Ian roberts Answer below, i created the below to deal with a few more scenarios and group the outputs together;

<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>

解决方案

Since you refer to format-dateTime you must be in XSLT 2.0, so you could approach it using regular expressions. If you know you'll always have one of these three forms then you could use 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>

Each of your example formats will match exactly one of the three alternatives in the pattern, and all the regex-group calls for the non-matching alternatives will produce empty strings.

这篇关于XSLT日期格式化的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆