使用XSLT格式化日期(字符串)

时间:2017-11-17 10:23:20

标签: xml xslt

关于这一特定主题有很多问题/答案,但似乎都没有解决我的具体问题。我也是一个完整的菜鸟,所以就是那个;-)。我将以下XML从应用程序发送到一个中间件。在那个中间件中,我正在捕获XML并提取数据。我最后一个挑战是重新格式化一段表示日期的字符串数据,该数据位于<now></now>标记内。

<?xml version="1.0" encoding="UTF-8"?>
    <Body>
        <send_message xmlns="urn:xyztech:agent">
            <user>
                <now>2017-11-15T13:38:11+00:00</now>
                <company>xyz.demo</company>
            </user>
        </send_message>
    </Body>

我正在使用Apigee作为中间件,需要一个XSL脚本来操作日期(使其更清洁 - 类似于15/11/2017或15.11.2017,我不想要时间) 。我已经尝试了几个我见过的例子,但似乎没有一个适合我。不幸的是,作为菜鸟,我实际上无法调试这些示例中出现的错误(例如,无法从命名空间参考中找到函数),我真的很感激一些帮助/指导。

如果我可以使用已经在XSL中提取数据的XPath,那将是非常光滑的:

<Variable name="now" type="date">
    <XPath>//Envelope/Body/send_message/user/now</XPath>
</Variable>

我已经看到了一个解决方案,但我觉得Apigee不支持XPath 2.0,所以format-date($d,"[D]-[M]-[Y]")也不是一个可行的选择。感谢任何/所有帮助...

3 个答案:

答案 0 :(得分:1)

这个怎么样:

<xsl:variable name="onlydate" select="substring-before('2017-11-15T13:38:11+00:00', 'T')"/>
<xsl:variable name="tokens" select="tokenize($onlydate, '-')"/>
<xsl:value-of select="concat($tokens[3], '.', $tokens[2], '.', $tokens[1])"/>

这对我有用,我得到了输出&#39; 15.11.2017&#39;。

  • Substring-before返回指定字符串之前的字符串 occours。
  • Tokenize将参数拆分为给定的数组 字符。

答案 1 :(得分:1)

“我有一种感觉”不是解决问题的正确方法。只需检查Apigee是否“理解”XSLT 2.0。

如果是,请使用format-date功能。 请注意以下示例中给出格式的方式。 它提供适当大小的日/月/年部分。

另一个重要细节:您的源XML使用命名空间 并且脚本引用它的元素(now)。所以:

  • 此命名空间必须包含在stylesheet标记中 命名空间引用(我使用xyz)。
  • 必须使用此命名空间引用提供now元素。

所以整个脚本可以如下:

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:xs="http://www.w3.org/2001/XMLSchema"
  xmlns:xyz="urn:xyztech:agent">
  <xsl:output indent="yes"/>
  <xsl:strip-space elements="*"/>

  <xsl:template match="xyz:now">
    <xsl:copy>
      <xsl:variable name="srcDate" select="substring-before(., 'T')" />
      <xsl:value-of select="format-date(xs:date($srcDate),'[D01].[M01].[Y0001]')"/>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="node()|@*">
    <xsl:copy><xsl:apply-templates select="node()|@*"/></xsl:copy>
  </xsl:template>
</xsl:stylesheet>

我使用 http://xsltransform.net/ 在您的来源上对其进行了测试,但它确实有效。

当然,最简单的检查方法是在您的环境中尝试此脚本。

答案 2 :(得分:0)

答案(完整的解决方案),采取一些Christian Mosz&amp; amp;上面提到了valdi_bo,@ frienddemann_bach的最后一个非常有用的解决方案和解释(来自我提出的另一个问题)就是这个,就像我需要的完整XSL一样:

<?xml version='1.0'?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    xmlns:ms="urn:schemas-microsoft-com:xslt">

<xsl:template match="@* | node()">
    <xsl:copy>
        <xsl:apply-templates select="@* | node()"/>
    </xsl:copy>
</xsl:template>

<xsl:template match="now">
  <now>
    <xsl:variable name="srcDateTime" select="//Envelope/Body/send_message/user/now"/>
    <xsl:variable name="srcDate" select="substring-before($srcDateTime, 'T')" />
    <xsl:variable name="outDate" select="format-date(xs:date($srcDate),'[D01].[M01].[Y0001]')"/>
    <xsl:value-of select="$outDate" disable-output-escaping="yes"/>
  </now>
</xsl:template>
</xsl:stylesheet>

虽然这里的前两个答案提供了日期格式的解决方案,但我不得不面对的问题是不理解为什么所有其他标签都被撕掉了。第一个(附加)模板修复了(它用于不做任何更改,因此第二个模板仅在我在第二个模板中选择的节点上覆盖“无更改”。 非常感谢帮助过的每个人。作为一个菜鸟(通过简单地学习并完成它来学习),我需要完整的解决方案和解释。我知道这有点“请为我做”,但这一切都增加了知识,这就是重点。再次感谢所有人。