根据日期使用 XSL 从 XML 中过滤用户?

Filtering users from XML with XSL based on date?

我有一个例程,我根据 XML 文件中的数据为用户分配成员资格。但是,消息来源最近在成员资格中引入了时间范围,我现在需要根据活动时间范围进行过滤。听起来很简单,对吧?

但是:

  1. 一些用户没有时间表。不能过滤它们。
  2. 一些用户有 2 个时间范围,其中一个、两个或 none 可能处于活动状态。必须选择一个或两个时间帧都处于活动状态的那些
  3. 有些用户的时间表有开始但没有结束。如果当前日期晚于开始日期,则必须选择它们。

这是一个例子:

<member>
<sourcedid>
<id>person_0f2f2d24-c19a-42d8-98bd-2f4147d693a60</id>
</sourcedid>
<idtype>1</idtype>
<role roletype="01">
<status>0</status>
<datetime>2020-08-01</datetime>
<timeframe>
<begin restrict="0">2020-08-01</begin>
<end restrict="0">2020-08-21</end>
<adminperiod>H2020/V2021</adminperiod>
</timeframe>
</role>
<role roletype="01">
<status>1</status>
<datetime>2020-08-22</datetime>
<timeframe>
<begin restrict="0">2020-08-22</begin>
<end restrict="0">2021-07-31</end>
<adminperiod>H2020/V2021</adminperiod>
</timeframe>
</role>
</member>

我们试过了,但它只适用于 1 个时间范围的人:

<xsl:for-each select="$sections">
                <xsl:variable name="group" select="."/>
                <xsl:variable name="memberships" select="key('membership', $group/sourcedid/id, $root)"/>
                <xsl:for-each select="$memberships">
                    <xsl:variable name="membership" select="."/>
                    <xsl:for-each select="$membership/member[role[@roletype eq '01']][my:filterMember(.)]">
                        <xsl:value-of select="$membership/sourcedid/id"/><xsl:value-of select="$delimiter"/>
                        <xsl:value-of select="sourcedid/id"/><xsl:value-of select="$break"/>
                    </xsl:for-each>
                </xsl:for-each>
</xsl:for-each>

    <xsl:function name="my:filterMember">
        <xsl:param name="member"/>
        <xsl:variable name="timeframes" select="$member/role/timeframe"/>
        <xsl:choose>
            <xsl:when test="$timeframes[begin/xs:date(.) gt current-date() or end/xs:date(.) lt current-date()]">
                <xsl:sequence select="false()"/>
            </xsl:when>
            <xsl:otherwise>
                <xsl:sequence select="true()"/>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:function>

有什么建议吗?

你不能简单地做:

select="member[some $timeframe in role/timeframe satisfies $timeframe/xs:date(begin) le current-date() and ($timeframe/xs:date(end) gt current-date() or not($timeframe/end))]"

这应该实现您的第二个和第三个条件。我不明白你的第一个条件:它可以双向阅读。如果“未过滤”表示“包含在选择中”,则只需添加 or not(role/timeframe).