我正在寻求建议,以验证一个包含日期的XML元素,并且我需要在XSLT中编写一个函数来验证它是否为YYYYMMDD格式。
这有点取决于您想在“验证”方面推进多远。
您可以这样做:
<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>
你说你正在使用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>
EXSLT日期和时间 函数在这里应该很有用。我相信他们的parseDate函数会在失败时返回一个空字符串。这可能无法完全满足您的需求,但它可以解决一些更难的日期解析问题(例如,确定某些月份的天数是否有效,同时处理闰年规则等)。
最简单的方法是使用你的 XSLT 处理器的扩展函数。