Search code examples
xsltdatecompareperiod

Compare date-periods using XSLT


I have some experience with XSLT but now i've got myself a problem: I need to check if a period between a begin- and enddate completely covers an other period.

Here's a part of the xml:

<Parent ID="1">
  <StartDate>20050101</StartDate>
  <EndDate>20060131</EndDate>
  <Child ID="1">
    <StartDate>20050101</StartDate>
    <EndDate>20081231</EndDate>
  </Child>
</Parent>
<Parent ID="2">
  <StartDate>20060201</StartDate>
  <EndDate>20071231</EndDate>
  <Child ID="1">
    <StartDate>20050101</StartDate>
    <EndDate>20081231</EndDate>
  </Child>
</Parent>
<Parent ID="3">
  <StartDate>20080101</StartDate>
  <EndDate>20081231<EndDate>
  <Child ID="1">
    <StartDate>20050101</StartDate>
    <EndDate>20081231</EndDate>
  </Child>
</Parent>

So i need to check if the period between start and end of the Parent is fully covered by the period between start and end of the Child in XSLT and write the Parent and Child ID's to xml for fails.

Can someone give me a head start how to manage this in XSLT...?

I have full control over the structure of the XML so when it's easier with an other XML structure (with the same data) i can change it.

Thanks a lot!


Solution

  • Using simple string comparison this is easy, because your date format is big-endian. Here's a quick XSLT document I wrote up to test it out:

    <?xml version="1.0" encoding="UTF-8"?>
    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
      <xsl:output method="xml" version="1.0" indent="yes"/>
    
      <xsl:template match="/">
        <root>
          <xsl:for-each select="//Parent">
            <parent>
              <xsl:attribute name="id">
                <xsl:value-of select="@ID"/>
              </xsl:attribute>
              <xsl:choose>
                <xsl:when test="(Child/StartDate &lt;= StartDate) and 
                  (Child/EndDate &gt;= EndDate)">
                  <xsl:text>OK</xsl:text>
                </xsl:when>
                <xsl:otherwise>
                  <xsl:text>Not OK</xsl:text>
                </xsl:otherwise>
              </xsl:choose>
            </parent>
          </xsl:for-each>
        </root>
      </xsl:template>
    </xsl:stylesheet>
    

    Obviously you'll need your own checks to make sure that StartDate is before EndDate for both parent and child.