【问题标题】:Reformatting of strings重新格式化字符串
【发布时间】:2014-08-19 12:50:55
【问题描述】:

我有 XML,其中一些日期和日期时间字符串以某些特殊格式提供:

DDMMYYYYHHMM(24 小时格式的小时数)

我试图在 XSLT 中创建一个用户定义的函数,以便能够重新格式化这样的字符串(我知道如何在其他语言中执行此操作,但我还不知道如何在 XSLT 中执行此操作) .我的想法是这样的:

<xsl:value-of select="udf:reFormat('230820141345','DDMMCCYYHHmm','HH:mm:00')"/>

会导致:

13:45:00

<xsl:value-of select="udf:reFormat('230820141345','DDMMCCYYHHmm','CCYY-MM-DD')"/>

会导致:

2014-08-23

【问题讨论】:

  • 我的第一个想法是在输入字符串中找到位于“CCYY”位置的内容,并将其放在输出字符串中的“CCYY”位置。在这种情况下,使用的字母(在格式字符串中)就没有那么重要了。
  • 那是哪个版本的 XSLT 2.0?用户定义的函数听起来像 XSLT 2.0,在这种情况下,我将首先将输入格式 DDMMYYYYHHMM 转换为 xs:dateTime,对于进一步的格式化,我将使用内置的 w3.org/TR/xslt20/#format-date 函数。
  • 这是我的备份计划。但是正在寻找一个更“灵活”的解决方案,因为在中间件中有很多日期时间转换挑战。它是 Sonic 中的 XSLT 2.0。
  • 马丁的建议为什么不灵活?一旦您的日期类型为xs:dateTime,就有许多有用的现有函数。
  • Martins 的回答绝对灵活!我看到的挑战是日期、时间和日期时间字段不统一,因此我需要单独处理每种类型以使其成为 XSLT 中的日期、时间或日期时间。之后,格式化的可能性就像我需要的那样灵活。但我试图消除在格式化之前先转换它的需要。就像我写的那样,这可能是我将使用的方法。

标签: xml xslt xml-parsing


【解决方案1】:

正如评论中所述,显而易见的方法是将数据解析为 xs:dateTime,但这里有一个功能可以满足您的需求:

<xsl:function name="udf:reFormat">
    <xsl:param name="in"/>
    <xsl:param name="inPattern"/>
    <xsl:param name="outPattern"/>

    <!-- analyze $outPattern to find occurrence of any sequence of same charachter -->
    <xsl:analyze-string select="$outPattern" regex="(\w)\1+">
        <xsl:matching-substring>
            <xsl:variable name="match" select="."/>
            <!-- check if $match is in $inPattern -->
            <xsl:choose>
                <xsl:when test="contains($inPattern, $match)">
                    <!-- get position of $match in $inPattern -->
                    <xsl:variable name="positionInPattern"
                        select="string-length(substring-before($inPattern,$match))+1"/>
                    <!-- get substring from $in -->
                    <xsl:value-of select="substring($in, $positionInPattern, string-length($match))"/>
                </xsl:when>
                <xsl:otherwise>
                    <xsl:value-of select="."/>
                </xsl:otherwise>
            </xsl:choose>
        </xsl:matching-substring>
        <xsl:non-matching-substring>
            <xsl:value-of select="."/>
        </xsl:non-matching-substring>
    </xsl:analyze-string>

</xsl:function>

【讨论】:

  • 很好的解决方案,虽然您需要在模式字符之间使用分隔符 (udfReformat("121320142244","DDMMCCYYHHmm","HH:mm:00") 有效,但 udfReformat("121320142244","DDMMCCYYHHmm" "HHmm00") 失败)。如果我需要一个简单的转换而不需要先将输入转换为日期(时间),这对我有用。
  • 你说得对,那是我对正则表达式的不好...我调整了正则表达式,现在它也应该在没有分隔符的情况下工作。
  • 太好了,这非常适合快速转换。
猜你喜欢
  • 2011-02-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-03-31
  • 2015-04-01
  • 2012-08-16
  • 1970-01-01
相关资源
最近更新 更多