XSLT 1.0如何选取同一Date节点下两个日期中的较大值
XSLT 1.0 实现双日期取较晚值方案
之前方案失效原因
max()是XPath 2.0/XSLT 2.0新增函数,XSLT 1.0原生不支持,直接调用必然报错- 排序方案不生效的核心原因:两个日期同属一个
<Date>节点的文本内容,不是独立的节点集合,直接对<Date>节点排序无法作用到拆分后的单个日期值 - 你提供的日期为固定长度
YYYY-MM-DD±HH:MM格式,所有月、日、时区值均补零对齐,这类格式的字符串字典序和时间序完全一致,不需要复杂转换即可直接比较
最简实现(适用于日期间隔大于时区差的业务场景)
不需要额外依赖,直接拆分字符串后比较即可,样例XML结构:
<Date>2021-09-13-07:00 2021-12-25-08:00</Date>
对应XSLT处理逻辑:
<xsl:template match="Date"> <xsl:variable name="trimDateStr" select="normalize-space(.)"/> <!-- 按固定长度拆分两个日期,单个日期固定16位,中间间隔1个空格 --> <xsl:variable name="dateA" select="substring($trimDateStr, 1, 16)"/> <xsl:variable name="dateB" select="substring($trimDateStr, 18, 16)"/> <!-- 直接比较字符串取较大值,补零对齐的ISO格式下字典序等价于时间序 --> <xsl:choose> <xsl:when test="$dateA > $dateB"> <xsl:value-of select="$dateA"/> </xsl:when> <xsl:otherwise> <xsl:value-of select="$dateB"/> </xsl:otherwise> </xsl:choose> </xsl:template>
运行后会输出2021-12-25-08:00,符合预期。
精确时区换算实现(适用于日期间隔近、需规避跨时区偏差的场景)
如果两个日期间隔可能小于时区差(比如相差几小时跨天),可以先把两个日期换算为UTC基准的总分钟数再比较,避免时区导致的判断错误:
<!-- 复用模板:将带时区的日期字符串换算为UTC总分钟数 --> <xsl:template name="calcUTCMinutes"> <xsl:param name="dateInput"/> <!-- 拆分年、月、日字段 --> <xsl:variable name="year" select="number(substring($dateInput, 1, 4))"/> <xsl:variable name="month" select="number(substring($dateInput, 6, 2))"/> <xsl:variable name="day" select="number(substring($dateInput, 9, 2))"/> <!-- 拆分时区偏移量 --> <xsl:variable name="tzFlag" select="substring($dateInput, 12, 1)"/> <xsl:variable name="tzHourOffset" select="number(substring($dateInput, 13, 2))"/> <xsl:variable name="tzMinOffset" select="number(substring($dateInput, 16, 2))"/> <!-- 计算基准日总分钟数,普通业务场景下该粗略计算精度足够,高精度需求可补充闰年计算逻辑 --> <xsl:variable name="baseMinutes" select="($year*365 + floor(($month - 1)*30.4) + $day) * 1440"/> <!-- 按时区偏移换算为UTC时间,XSLT1.0兼容写法 --> <xsl:variable name="offsetMinutes" select="($tzHourOffset*60 + $tzMinOffset) * (($tzFlag = '-') * 2 - 1)"/> <xsl:value-of select="$baseMinutes + $offsetMinutes"/> </xsl:template> <!-- 处理Date节点 --> <xsl:template match="Date"> <xsl:variable name="trimDateStr" select="normalize-space(.)"/> <xsl:variable name="dateA" select="substring($trimDateStr, 1, 16)"/> <xsl:variable name="dateB" select="substring($trimDateStr, 18, 16)"/> <!-- 分别换算两个日期的UTC分钟数 --> <xsl:variable name="dateAUTC"> <xsl:call-template name="calcUTCMinutes"> <xsl:with-param name="dateInput" select="$dateA"/> </xsl:call-template> </xsl:variable> <xsl:variable name="dateBUTC"> <xsl:call-template name="calcUTCMinutes"> <xsl:with-param name="dateInput" select="$dateB"/> </xsl:call-template> </xsl:variable> <!-- 比较UTC值取对应日期 --> <xsl:choose> <xsl:when test="$dateAUTC > $dateBUTC"> <xsl:value-of select="$dateA"/> </xsl:when> <xsl:otherwise> <xsl:value-of select="$dateB"/> </xsl:otherwise> </xsl:choose> </xsl:template>
内容的提问来源于stack exchange,提问作者user19257435
相关产品推荐
相关产品推荐

