检查 XSLT 中的字符串是否为有效日期

Beg*_*ner 3 xml xslt xalan

我有一个 xml 文档,其中有一些日期节点,我试图获取它们的值(如果这些值是有效日期,否则为空字符串)。

XML:

<root>
  <START_DATE><![CDATA[03/05/2015]]></START_DATE>
  <START_DATE><![CDATA[05/05/2015]]></START_DATE>
  <START_DATE><![CDATA[Online]]></START_DATE>
</root>
Run Code Online (Sandbox Code Playgroud)

XSLT:

<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:xs="http://www.w3.org/2001/XMLSchema" version="1.0">
  <xsl:output method="text" indent="yes" />
  <xsl:template match="@*|node()">
    <xsl:apply-templates select="@*|node()" />
  </xsl:template>

  <xsl:template match="START_DATE">
    <xsl:copy>
        <xsl:value-of select="if(string(normalize-space(.)) castable as xs:date) then normalize-space(.) else ''"></xsl:value-of>
    </xsl:copy>
    <xsl:text>&#44;</xsl:text>
  </xsl:template>
</xsl:transform>
Run Code Online (Sandbox Code Playgroud)

输出:

,,,
Run Code Online (Sandbox Code Playgroud)

预期的:

03/05/2015,05/05/2015,,
Run Code Online (Sandbox Code Playgroud)

mic*_*57k 5

如果值是有效日期,则获取它们的值,否则为空字符串

Xalan 是一个 XSLT 1.0 处理器。XSLT 1.0 没有“日期”的概念,因此您必须自己执行验证。确切的方法取决于“有效日期”在这种情况下的确切含义。

如果足以确保声称是日期的字符串被格式化为日期(即恰好具有此模式“##/##/####”),则测试可以非常简单:

<xsl:if test="translate(., '123456789', '000000000') = '00/00/0000'">
    <!-- result if valid -->
</xsl:if>
Run Code Online (Sandbox Code Playgroud)

如果您还需要测试所声称的日期是否是公历中的有效日期(例如,不是“13/13/2015”),那么事情就会变得更加复杂。


关于 XSLT 2.0 的注释:

在 XSLT 2.0 中,您可以用来castable as xs:date测试日期是否有效。但是,即使格式为MM/DD/YYYY或 的有效日期DD/MM/YYYY也不会通过此测试。您必须YYYY-MM-DD先将这些字符串转换为格式。