首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >XSLT数据格式

XSLT数据格式
EN

Stack Overflow用户
提问于 2014-04-04 16:41:55
回答 3查看 2.5K关注 0票数 3

我曾在这里看过各种各样的建议,但没有一个能真正解决我的问题。由于XML的来源,我可以收到以下三种格式的日期;

代码语言:javascript
复制
04-04-2014(DD-MM-YYYY)
04-Apr-2014(DD-MMM-YYYY)
2014-04-04(YYYY-MM-DD)

我希望有一个函数或简单的命令,将所有这些(第三个除外,但能够识别第三个是正确的)转换为YYYY DD。

我现在有很长的时间/什么时候/什么时候做这件事,但是肯定有一个更简单的方法。我现在的XSLT做了以下工作;

代码语言:javascript
复制
<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下面的答案,我创建了下面的内容来处理更多的场景,并将输出组合在一起;

代码语言:javascript
复制
<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>
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2014-04-04 17:25:52

由于您引用的是format-dateTime,所以您必须在XSLT2.0中,所以可以使用正则表达式来处理它。如果你知道你总是有这三种形式中的一种,那么你可以使用analyze-string

代码语言:javascript
复制
<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调用都将生成空字符串。

票数 2
EN

Stack Overflow用户

发布于 2014-04-05 15:43:52

即使在XSLT1.0中,如果您关注的是不同格式的结构,而不是它们的内容,那么问题就变得相当简单。

代码语言:javascript
复制
<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>
票数 3
EN

Stack Overflow用户

发布于 2014-04-05 13:58:44

下面是一个函数,将类似的正则表达式和月份序列用作另一个答案:

代码语言:javascript
复制
<?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>
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/22868423

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档