Xml 字符串的重新格式化
我有一些XML文件,其中一些日期和日期时间字符串是以特殊格式提供的: DDMMYYYYHMM(24小时格式的小时数) 我试图在XSLT中创建一个用户定义的函数,以便能够重新格式化这样的字符串(我知道如何在其他语言中这样做,但我还不知道如何在XSLT中这样做)。我的想法是:Xml 字符串的重新格式化,xml,xslt,xml-parsing,Xml,Xslt,Xml Parsing,我有一些XML文件,其中一些日期和日期时间字符串是以特殊格式提供的: DDMMYYYYHMM(24小时格式的小时数) 我试图在XSLT中创建一个用户定义的函数,以便能够重新格式化这样的字符串(我知道如何在其他语言中这样做,但我还不知道如何在XSLT中这样做)。我的想法是: <xsl:value-of select="udf:reFormat('230820141345','DDMMCCYYHHmm','HH:mm:00')"/> 及 正如注释中所述,最明显的方法是将数据解析为xs:
<xsl:value-of select="udf:reFormat('230820141345','DDMMCCYYHHmm','HH:mm:00')"/>
及
正如注释中所述,最明显的方法是将数据解析为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>
我的第一个想法是找到输入字符串中“CCYY”位置上的内容,然后将其放在输出字符串中“CCYY”位置上。在这种情况下,使用的字母(格式字符串)就没有那么重要了。这是XSLT2.0的哪个版本?用户定义的函数听起来像XSLT 2.0,在这种情况下,我首先将输入格式ddmmyyyhhmm
转换为xs:dateTime
,对于进一步的格式,我将使用内置函数。这是我的备份计划。但是我们正在寻找一个更“灵活”的解决方案,因为在中间件中有很多日期-时间转换挑战。这是Sonic中的XSLT2.0。为什么Martin的建议不灵活?一旦您的日期是xs:dateTime
类型,就有一系列有用的现有函数。Martins的答案绝对灵活!我看到的挑战是date、time和datetime字段并不统一,因此我需要单独处理每种类型,使之成为XSLT中的日期、时间或datetime。之后,格式的可能性是灵活的,因为我需要。但我试图消除在格式化之前先转换它的需要。就像我写的,这可能是我将要使用的方法。很好的解决方案,尽管在模式字符之间需要一个分隔符(udfReformat(“121320142244”,“DDMMCCYYHHmm”,“HH:mm:00”)可以工作,但udfReformat(“121320142244”,“DDMMCCYYHHmm”,“HHmm00”)失败)。如果我需要一个简单的转换,而不需要首先将输入转换为日期(时间),那么这对我来说很有用。。。我现在调整了正则表达式,它在没有分隔符的情况下也可以工作。太好了,这非常适合快速转换。
<xsl:value-of select="udf:reFormat('230820141345','DDMMCCYYHHmm','CCYY-MM-DD')"/>
2014-08-23
<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>