XSLT函数用于验证日期格式为YYYYMMDD

3

我正在寻求建议,以验证一个包含日期的XML元素,并且我需要在XSLT中编写一个函数来验证它是否为YYYYMMDD格式。

4个回答

5
注意:以下内容适用于没有日期数据类型的XSLT版本1.0。如果您的XSLT处理器支持更高版本,请使用其中一个内置日期函数。

这有点取决于您想在“验证”方面推进多远。

您可以这样做:

<xsl:if test="
  string-length(date) = 8 
  and translate(date, '0123456789', '') = ''
">
  <!-- date looks like it could be valid -->
</xsl:if>

您还可以进行更全面的检查:

<xsl:if test="
  string-length(date) = 8 
  and translate(date, '0123456789', '') = ''
  and number(substring(date, 1, 4)) &gt;= 1970
  and number(substring(date, 5, 2)) &lt;= 12
  and number(substring(date, 7, 2)) &lt;= 31
">
  <!-- date looks like it could really be valid -->
</xsl:if>

然而,后者仍然允许20090231。如果你想排除这种情况,调用某种扩展函数可能是不可避免的。

你如何验证包含少于31天的月份(例如:二月)的日期? - MK Vimalan
1
请阅读我的回答。我已经在那里写下来了。 - Tomalak

3

你说你正在使用Saxon。如果是最近的版本(8.x,9.x),那么它是一个XSLT 2.0处理器,因此支持使用正则表达式和XML Schema原始数据类型(包括xs:date)解析字符串的xsl:analyze-string指令。所以你可以使用正则表达式将日期拆分为组件,然后将结果转换为ISO 8601日期格式,尝试将其转换为xs:date以验证月份和日期(这应该正确处理闰年等):

<xsl:variable name="date-string" select="..."/>

...
<xsl:analyze-string select="$date-string" regex="^(\d{4})(\d{2})(\d{2})$">
  <xsl:matching-substring>
    <xsl:variable name="$year" select="xs:integer(regex-group(1))"/>
    <xsl:variable name="$month" select="xs:integer(regex-group(2))"/>
    <xsl:variable name="$day" select="xs:integer(regex-group(3))"/>
    <xsl:variable name="$date-iso" select="concat($year, '-', $month, '-', $day)" />
    <xsl:choose>
      <xsl:when test="$date-iso castable as xs:date">
        <xsl:variable name="$date" select="$date-iso cast as xs:date" />
        <!-- $date now contains an xs:date value, which you can work with using XPath 2.0 date functions -->
        ...
      </xsl:when>
      <xsl:otherwise>
        <!-- $date-string was in YYYYMMDD format, but values for some of components were incorrect (e.g. February 31). -->
        ...
      </xsl:otherwise>
    </xsl:choose>
  </xsl:matching-substring>
  <xsl:non-matching-substring>
    <!-- $date-string wasn't in YYYYMMDD format at all -->
    ...
  </xsl:non-matching-substring>
</xsl:analyze-string>

1

EXSLT日期和时间 函数在这里应该很有用。我相信他们的parseDate函数会在失败时返回一个空字符串。这可能无法完全满足您的需求,但它可以解决一些更难的日期解析问题(例如,确定某些月份的天数是否有效,同时处理闰年规则等)。


1

最简单的方法是使用你的 XSLT 处理器的扩展函数。


我正在使用SAXON解析器,您有关于如何扩展XSLT函数的更多建议吗? - mshafrir
这里是SAXON可扩展性文档:http://www.saxonica.com/documentation/extensibility/intro.html - Lloyd
@Lloyd:你的链接已经失效了 :( - Svish
1
@Svish 试试这个:http://www.saxonica.com/documentation/index.html#!extensibility - Lloyd

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接