XSLT를 사용하여 날짜 기간을 비교하십시오
문제
XSLT에 대한 경험이 있지만 이제 나 자신이 문제를 겪었습니다. 시작과 종말 사이의 기간이 다른 기간을 완전히 포함하는지 확인해야합니다.
다음은 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>
따라서 부모의 시작과 끝 사이의 기간이 XSLT에서 아동의 시작과 끝 사이의 기간에 의해 완전히 덮여 있는지 확인하고 부모와 자식 ID를 XML에 써서 실패합니다.
누군가 나에게 XSLT에서 이것을 관리하는 방법을 제시 할 수 있습니까?
XML의 구조를 완전히 제어 할 수 있으므로 다른 XML 구조 (동일한 데이터와 함께)가 더 쉬울 때 변경할 수 있습니다.
정말 감사합니다!
해결책
간단한 문자열 비교를 사용하면 날짜 형식이 큰 엔디언이기 때문에 이것은 쉽습니다. 다음은 테스트하기 위해 작성한 빠른 XSLT 문서입니다.
<?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 <= StartDate) and
(Child/EndDate >= 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>
분명히 당신은 당신의 수표가 필요합니다. StartDate
전입니다 EndDate
부모와 자녀 모두.
다른 팁
다음은 XSLT 2.0에서 직접 수행하는 예입니다. 대부분의 날짜 구분자와 함께 작동해야합니다.
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0"
exclude-result-prefixes="functx xs"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:functx="http://www.functx.com"
xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xsl:template match="/">
<dates>
<dateBetween>
<xsl:choose>
<xsl:when test="functx:dateBetween('02-01-2009','01-01-2009','03-01-2009')=true()">
<xsl:text>date lays between given dates</xsl:text>
</xsl:when>
<xsl:otherwise>
<xsl:text>date is not between given dates</xsl:text>
</xsl:otherwise>
</xsl:choose>
</dateBetween>
<currentDateBetween>
<xsl:choose>
<xsl:when test="functx:currentDateBetween('01-01-2000','01-01-2019')=true()">
<xsl:text>current date lays between given dates</xsl:text>
</xsl:when>
<xsl:otherwise>
<xsl:text>current date is not between given dates</xsl:text>
</xsl:otherwise>
</xsl:choose>
</currentDateBetween>
</dates>
</xsl:template>
<!--
Function: dateBetween
Description: This function will check if a dates is between given dates
Input: Input date, Input start date, Input end date
Output: Boolean true if beween param 2 and 3
Created: 21-09-2012 by Raymond Meester
-->
<xsl:function name="functx:dateBetween">
<xsl:param name="param1"/>
<xsl:param name="param2"/>
<xsl:param name="param3"/>
<xsl:variable name ="dateToCheck" select="functx:mmddyyyy-to-date($param1)"/>
<xsl:variable name ="startDate" select="functx:mmddyyyy-to-date($param2)"/>
<xsl:variable name ="endDate" select="functx:mmddyyyy-to-date($param3)"/>
<xsl:variable name ="true" as="xs:boolean" select="true()"/>
<xsl:variable name ="false" as="xs:boolean" select="false()"/>
<xsl:choose>
<xsl:when test="$startDate < $dateToCheck and $dateToCheck < $endDate"><xsl:value-of select="$true"/></xsl:when>
<xsl:otherwise><xsl:value-of select="$false"/></xsl:otherwise>
</xsl:choose>
</xsl:function>
<!--
Function: currentDateBetween
Description: This function will check if a dates is between given dates
Input: Input date, Input start date, Input end date
Output: Boolean true if beween param 2 and 3
Created: 21-09-2012 by Raymond Meester
-->
<xsl:function name="functx:currentDateBetween">
<xsl:param name="param1"/>
<xsl:param name="param2"/>
<xsl:variable name ="startDate" select="functx:mmddyyyy-to-date($param1)"/>
<xsl:variable name ="endDate" select="functx:mmddyyyy-to-date($param2)"/>
<xsl:variable name ="true" as="xs:boolean" select="true()"/>
<xsl:variable name ="false" as="xs:boolean" select="false()"/>
<xsl:choose>
<xsl:when test="$startDate < current-date() and current-date() < $endDate"><xsl:value-of select="$true"/></xsl:when>
<xsl:otherwise><xsl:value-of select="$false"/></xsl:otherwise>
</xsl:choose>
</xsl:function>
<!--
Function: mmddyyyy-to-date
Description: The functx:mmddyyyy-to-date function converts $dateString into a valid xs:date value. The order of the digits in $dateString must be MMDDYYYY, but it can contain any (or no) delimiters between the digits.
Input: Input string
Output: Return date
Created: 2007-02-26 http://www.xsltfunctions.com/xsl/functx_mmddyyyy-to-date.html
-->
<xsl:function name="functx:mmddyyyy-to-date" as="xs:date?"
xmlns:functx="http://www.functx.com">
<xsl:param name="dateString" as="xs:string?"/>
<xsl:sequence select="if (empty($dateString)) then () else if (not(matches($dateString,'^\D*(\d{2})\D*(\d{2})\D*(\d{4})\D*$'))) then error(xs:QName('functx:Invalid_Date_Format')) else xs:date(replace($dateString,'^\D*(\d{2})\D*(\d{2})\D*(\d{4})\D*$','$3-$1-$2'))"/>
</xsl:function>
</xsl:stylesheet>
무슨 일이야 number(Child/StartDate) <= number(Parent/StartDate) and number(Child/EndDate) >= number(Parent/EndDate)
?
이것은 완전한 솔루션이 아니지만 날짜 조작에 대한 ExSLT 확장을 확인하고 싶을 수도 있습니다. 여기.
그러나 나는 몇 가지를 만드는 것을 고려할 것입니다 XSLT 확장 기능, 사용 Joda Time의 간격 추상화. XSLT에서 직접 시도하는 것보다 훨씬 쉽고 빠릅니다.