使用XSLT查找日期是否在日期范围内

时间:2019-05-29 06:48:49

标签: xslt

我有以下xml:

<?xml version="1.0" encoding="UTF-8"?>
<divisions>
   <userProvidedEffDate>12/31/2002</userProvidedEffDate>
   <division>
      <GroupNumber>001</GroupNumber>
      <GroupEffDt>01/01/2000</GroupEffDt>
      <GroupExpDt>12/31/9999</GroupExpDt>
   </division>
   <division>
      <GroupNumber>002</GroupNumber>
      <GroupEffDt>01/01/2000</GroupEffDt>
      <GroupExpDt>12/31/2001</GroupExpDt>
   </division>
</divisions>

现在,我想基于<userProvidedEffDate>的值,使用XSLT 1.0转换上述xml。如果<userProvidedEffDate><division>'s <GroupEffDt><GroupExpDt>(包括两端)的日期范围之间,则显示该划分。例如,上面的输入xml应该基于<userProvidedEffDate>值12/31/2002进行如下转换。

<?xml version="1.0" encoding="UTF-8"?>
<divisions>
   <userProvidedEffDate>12/31/2002</userProvidedEffDate>
   <division>
      <GroupNumber>001</GroupNumber>
      <GroupEffDt>01/01/2000</GroupEffDt>
      <GroupExpDt>12/31/9999</GroupExpDt>
   </division>
</divisions>

感谢您的帮助。

2 个答案:

答案 0 :(得分:1)

作为切换到Saxon 9的示例,如果必须在XSLT 1.0中执行此操作(不具有任何扩展功能),则必须将日期转换为YYYYMMDD格式的数字。

例如

<xsl:variable name="userProvidedEffDate" select="number(concat(substring(userProvidedEffDate, 7, 4), substring(userProvidedEffDate, 1, 2), substring(userProvidedEffDate, 4, 2)))" />

尝试使用此XSLT

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
  <xsl:output method="xml" indent="yes" />

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

  <xsl:template match="divisions">
    <xsl:variable name="userProvidedEffDate" select="number(concat(substring(userProvidedEffDate, 7, 4), substring(userProvidedEffDate, 1, 2), substring(userProvidedEffDate, 4, 2)))" />
    <xsl:copy>
      <xsl:apply-templates select="@*|userProvidedEffDate" />
      <xsl:apply-templates select="division
                                     [number(concat(substring(GroupEffDt, 7, 4), substring(GroupEffDt, 1, 2), substring(GroupEffDt, 4, 2))) &lt;= $userProvidedEffDate
                                      and number(concat(substring(GroupExpDt, 7, 4), substring(GroupExpDt, 1, 2), substring(GroupExpDt, 4, 2))) &gt;= $userProvidedEffDate]" />
    </xsl:copy>
  </xsl:template>
</xsl:stylesheet>

当然,如果您可以控制XML,那么一个简单的解决方案就是首先将YYYYMMDD格式的日期放在XML中

答案 1 :(得分:1)

这很乏味,但不太困难:

XSLT 1.0

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>

<xsl:template match="/divisions">
    <xsl:variable name="userDate">
        <xsl:value-of select="substring(userProvidedEffDate, 7, 4)"/>
        <xsl:value-of select="substring(userProvidedEffDate, 1, 2)"/>
        <xsl:value-of select="substring(userProvidedEffDate, 4, 2)"/>
    </xsl:variable>
    <xsl:copy>
        <xsl:for-each select="division">     
            <xsl:variable name="effDate">
                <xsl:value-of select="substring(GroupEffDt, 7, 4)"/>
                <xsl:value-of select="substring(GroupEffDt, 1, 2)"/>
                <xsl:value-of select="substring(GroupEffDt, 4, 2)"/>
            </xsl:variable>
            <xsl:variable name="expDate">
                <xsl:value-of select="substring(GroupExpDt, 7, 4)"/>
                <xsl:value-of select="substring(GroupExpDt, 1, 2)"/>
                <xsl:value-of select="substring(GroupExpDt, 4, 2)"/>
            </xsl:variable>
            <xsl:if test="$effDate &lt;= $userDate and $userDate &lt;= $expDate">
                <xsl:copy-of select="."/>
            </xsl:if>
        </xsl:for-each>
    </xsl:copy>
</xsl:template>

</xsl:stylesheet>