我正在寻找建议来验证保存日期的XML元素,我需要在XSLT中使用一个函数来验证它是否是YYYYMMDD格式。
答案 0 :(得分:5)
注意:以下内容适用于XSLT 1.0版,它没有日期数据类型。如果您的XSLT处理器支持never版本,请使用其中一个内置日期函数。
这取决于你想要推进“验证”的程度。
你可以这样做:
<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)) >= 1970
and number(substring(date, 5, 2)) <= 12
and number(substring(date, 7, 2)) <= 31
">
<!-- date looks like it could really be valid -->
</xsl:if>
然而,后者仍然允许20090231.如果你想要排除这种情况,调用某种扩展函数可能会变得不可避免。
答案 1 :(得分:3)
你说你正在使用撒克逊人。如果这是最新版本(8.x,9.x),那么它是一个XSLT 2.0处理器,因此,它支持使用正则表达式解析字符串的xsl:analyze-string
指令,以及XML Schema原始数据类型,包括xs:date
。因此,您可以使用正则表达式将日期拆分为组件,然后将结果转换为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>
答案 2 :(得分:1)
EXSLT Date and Time函数在这里应该很有用。我相信他们的parseDate函数会在失败时返回一个空字符串。它可能无法让你达到你想要的100%,但它应该解决日期解析中的一些更难的问题(弄清楚日期是否适用于特定月份,同时处理闰年规则等)。
答案 3 :(得分:1)
最简单的方法是使用XSLT处理器的扩展功能。