微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

xml – 如何使用XSLT检索最接近但不是在特定日期之后的元素?

给定具有日期属性的元素列表,例如,

<foo>
 <bar date="2001-04-15"/>
 <bar date="2002-01-01"/>
 <bar date="2005-07-04"/>
 <bar date="2010-11-10"/>
</foo>

我想使用XSLT检索最接近但不在给定日期之后的元素.

使用参数“2008-01-01”调用函数应打印< bar date =“2005-07-04”>.假设上下文节点已经是< foo>.

我不确定什么会更容易,但我也可以设置三个属性:日,月,年,而不是有一个日期属性.

解决方法

这是一个XSLT 2.0选项……

XML输入

<foo>
    <bar date="2001-04-15"/>
    <bar date="2005-07-04"/>
    <bar date="2002-01-01"/>
    <bar date="2010-11-10"/>
</foo>

XSLT 2.0

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema">
    <xsl:output indent="yes"/>
    <xsl:strip-space elements="*"/>

    <xsl:param name="threshold" select="xs:date('2008-01-01')"/>

    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="foo">
        <xsl:variable name="closestDate" as="node()*">
            <xsl:apply-templates select="bar[$threshold >= xs:date(@date)]">
                <xsl:sort select="@date" data-type="text"/>
            </xsl:apply-templates>                  
        </xsl:variable>
        <xsl:copy-of select="$closestDate[last()]"/>
    </xsl:template>

</xsl:stylesheet>

XML输出

<bar date="2005-07-04"/>

“foo”模板的说明……

<xsl:template match="foo">
    <!--First a variable named 'closestDate' is created by doing an 
        'xsl:apply-templates' to all 'bar' elements that have a '@date' 
        attribute that is less than or equal to the 'threshold' parameter 
        (which is '2008-01-01' in the example). Notice that both '@date' 
        and '$threshold' are cast as 'xs:date' so that the date comparison 
        will work correctly. Also,we use the 'as="node()*"' attribute to 
        cast the variable as zero or more nodes() so that each individual 
        'bar' can be accessed individually.-->
    <xsl:variable name="closestDate" as="node()*">
        <xsl:apply-templates select="bar[$threshold >= xs:date(@date)]">
            <!--This 'xsl:sort' is used to put all the 'bar' elements in order 
                based on the '@date' attribute.-->
            <xsl:sort select="@date" data-type="text"/>
        </xsl:apply-templates>
    </xsl:variable>
    <!--What we end up with for the 'closestDate' variable is this:
            <bar date="2001-04-15"/>
            <bar date="2002-01-01"/>
            <bar date="2005-07-04"/>
        In the following 'xsl:copy-of',we choose the last node 
        in 'closestDate'.-->
    <xsl:copy-of select="$closestDate[last()]"/>
</xsl:template>

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。