基于日期时间筛选最新CosignerName的XSLT 1.0实现问询
解决方案:XSLT 1.0筛选最新签署人姓名
核心思路
针对每个<Form>节点,我们需要:
- 遍历1-12的序号,关联对应序号的
CosignerName[N]、CosignerDate[N]、CosignerTime[N]字段 - 将日期时间转换为可直接比较的时间戳(比如
YYYYMMDDHHMMSS格式) - 筛选出时间戳最大的条目,提取对应的姓名
完整XSLT实现
1. 基础配置与命名空间
首先声明XSLT版本和节点集处理的命名空间(根据你的XSLT处理器调整,示例用MSXML的msxsl):
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl">
2. 时间戳生成模板
复用你已实现的时间戳逻辑,这里用字符串拼接生成可直接比较的时间戳:
<xsl:template name="generate-timestamp"> <xsl:param name="date"/> <!-- 输入格式:YYYY-MM-DD --> <xsl:param name="time"/> <!-- 输入格式:HH:MM:SS --> <!-- 转换为无分隔符的字符串,方便直接比较大小 --> <xsl:value-of select="concat( translate($date, '-', ''), translate($time, ':', '') )"/> </xsl:template>
3. 处理单个Form节点的核心逻辑
<!-- 定义1-12的序号节点集 --> <xsl:variable name="numbers"> <num>1</num><num>2</num><num>3</num><num>4</num><num>5</num><num>6</num> <num>7</num><num>8</num><num>9</num><num>10</num><num>11</num><num>12</num> </xsl:variable> <xsl:variable name="num-set" select="msxsl:node-set($numbers)"/> <!-- 匹配每个Form节点 --> <xsl:template match="Form"> <!-- 收集所有有效签署人(排除日期/时间为空的条目) --> <xsl:variable name="signers"> <xsl:for-each select="$num-set/num"> <xsl:variable name="n" select="."/> <!-- 动态关联对应序号的字段 --> <xsl:variable name="date-field" select="../*[local-name() = concat('CosignerDate', $n)]"/> <xsl:variable name="time-field" select="../*[local-name() = concat('CosignerTime', $n)]"/> <xsl:if test="$date-field != '' and $time-field != ''"> <signer> <name><xsl:value-of select="../*[local-name() = concat('CosignerName', $n)]"/></name> <timestamp> <xsl:call-template name="generate-timestamp"> <xsl:with-param name="date" select="$date-field"/> <xsl:with-param name="time" select="$time-field"/> </xsl:call-template> </timestamp> </signer> </xsl:if> </xsl:for-each> </xsl:variable> <xsl:variable name="signer-set" select="msxsl:node-set($signers)"/> <!-- 筛选时间戳最大的签署人 --> <xsl:variable name="max-timestamp" select="$signer-set/signer[not(../signer/timestamp > timestamp)]/timestamp"/> <latest-cosigner> <!-- 如果有多个时间戳相同的条目,取第一个 --> <xsl:value-of select="$signer-set/signer[timestamp = $max-timestamp][1]/name"/> </latest-cosigner> </xsl:template> <!-- 根节点模板 --> <xsl:template match="/"> <results> <xsl:apply-templates select="//Form"/> </results> </xsl:template> </xsl:stylesheet>
关键问题解决说明
- 动态字段关联:通过
local-name() = concat('CosignerDate', $n)动态匹配对应序号的字段,确保同一N的三个字段正确关联。 - 时间戳映射:将每个签署人的姓名、时间戳封装到临时
<signer>节点中,直接建立关联关系,避免映射丢失。 - 最大时间戳筛选:利用
not(../signer/timestamp > timestamp)找到不存在更大时间戳的条目,无需提前排序,直接定位最新记录。
注意事项
- 如果你的XSLT处理器是Saxon等,需要将
msxsl:node-set替换为exsl:node-set,并添加对应的命名空间xmlns:exsl="http://exslt.org/common"。 - 若存在日期/时间格式不统一的情况,需先在时间戳模板中做格式校验或转换。
内容的提问来源于stack exchange,提问作者Jeramy
相关产品推荐
相关产品推荐

