XSLT 1.0 の場合、これは注意が必要です。最初のクラスの値としての日付や、文字列の辞書式比較をサポートしていないからです。また、(仕様ごとに)一時変数でノードセットを構築し、そのセットから個々のノードを抽出することはサポートされていません。それにもかかわらず、あなたが望むことはいくつかのトリックで可能です.
日付が YYYY-MM-DD であるということは、ハイフンを取り除いて結果の文字列を数値として扱う場合、これらの数値を数値順に並べ替えると、元の日付を時系列で並べ替えるのと同じ結果になることを意味します。また、XSLT には更新可能な変数がありませんが、兄弟ノードに 1 つずつ再帰的に適用され、テンプレート パラメーターで状態を渡すテンプレートを使用することで、同様の効果を得ることができます。
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:param name="targetDate" select="20080101" />
<xsl:template match="foo">
<!-- find the first "candidate" bar whose date is before the target date -->
<xsl:apply-templates select="(bar[translate(@date, '-', '') < $targetDate])[1]" />
</xsl:template>
<xsl:template match="bar">
<xsl:param name="closest" select="." />
<!-- find the next candidate bar whose date is before the target date -->
<xsl:variable name="nextCandidate"
select="(following-sibling::bar[translate(@date, '-', '') < $targetDate])[1]" />
<xsl:choose>
<xsl:when test="$nextCandidate">
<xsl:choose>
<xsl:when test="translate($nextCandidate/@date, '-', '') > translate($closest/@date, '-', '')">
<!-- $nextCandidate is closer to the target than the current $closest -->
<xsl:apply-templates select="$nextCandidate">
<xsl:with-param name="closest" select="$nextCandidate" />
</xsl:apply-templates>
</xsl:when>
<xsl:otherwise>
<!-- current $closest is still the closest -->
<xsl:apply-templates select="$nextCandidate">
<xsl:with-param name="closest" select="$closest" />
</xsl:apply-templates>
</xsl:otherwise>
</xsl:choose>
</xsl:when>
<xsl:otherwise>
<!-- no more candidates, so $closest is the node we require -->
<xsl:copy-of select="$closest" />
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>