Reputation: 3
I am trying to filter the list using xslt so that it only shows the item within two dates. But somehow the result is incorrect where only one item displayed. the statement I used is:
<xsl:variable name="Rows"
select="/dsQueryResponse/Rows/Row[(number(concat(substring(ddwrt:FormatDateTime(string(ddwrt:Today()), 1033, 'yyyy'),0,5),substring(ddwrt:FormatDateTime(string(@DateOfBirth), 1033, 'MM'),0,3),substring(ddwrt:FormatDateTime(string(@DateOfBirth),1033,'dd'),1,3))))
>= (number(translate(ddwrt:FormatDateTime(string(ddwrt:Today()),1033,'yyyyMMdd'),' ','')))
and(number(concat(substring(ddwrt:FormatDateTime(string(ddwrt:Today()), 1033, 'yyyy'),0,5),substring(ddwrt:FormatDateTime(string(@DateOfBirth), 1033, 'MM'),0,3),substring(ddwrt:FormatDateTime(string(@DateOfBirth),1033,'dd'),1,3))))
<= (number(translate(ddwrt:FormatDateTime(string(ddwrt:Today()),1033,'yyyyMMdd'),'',''))+7)]"/>
What I am trying to do is to display the employee who is celebrating their birthday this week by concatenate the day and month of their birthdate with today's year and convert this to number. then check if this new date is >= today's date (also convert to number) and <= today's date + 7 days.
I am new in xslt and been trying to solve this problem more than a week now. I am really appreciate if anyone can help me.
Upvotes: 0
Views: 948
Reputation: 338316
I believe you can use an XSLT extension to solve your problem more elegantly.
Some extension functions are provided by the ddwrt
namespace, but none of them are very useful for date arithmetic.
Since I have no SharePoint to test any code with, I'm showing a script extension based on VBScript. Here is an IsAnniversary()
function along with some supporting code.
<xsl:stylesheet
version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:ddwrt="http://schemas.microsoft.com/WebParts/v2/DataView/runtime"
xmlns:msxsl="urn:schemas-microsoft-com:xslt"
xmlns:udf="http://tempuri.org/udf"
exclude-result-prefixes="ddwrt msxsl udf"
>
<xsl:template match="/">
<xsl:for-each select="
/dsQueryResponse/Rows/Row[udf:IsAnniversary(@DateOfBirth, 7)]
">
<xsl:value-of select="@DateOfBirth" />
</xsl:for-each>
</xsl:template>
<msxsl:script language="VBScript" implements-prefix="udf">
<![CDATA[
Option Explicit
Function FirstValue(Input)
If IsObject(Input) Then ' it's an IXMLDOMNodeList
If Input.length > 0 Then FirstValue = Input.item(0).text Else FirstValue = Empty
Else
FirstValue = Input
End If
End Function
Function ParseDate(Input)
Input = FirstValue(Input)
Input = Split(Input & "T", "T")(0) ' handle ISO 8601 datetimes
If IsDate(Input) Then ParseDate = CDate(Input) Else ParseDate = Empty
End Function
Function ParseInt(Input)
Input = FirstValue(Input)
If IsNumeric(Input) Then ParseInt = CInt(Input) Else ParseInt = Empty
End Function
Function IsAnniversary(Input, WithinDays)
Dim TheDate, Diff
IsAnniversary = False
TheDate = ParseDate(Input)
WithinDays = ParseInt(WithinDays)
If Not (IsEmpty(TheDate) Or IsEmpty(WithinDays)) Then
TheDate = DateAdd("yyyy", Year(Now()) - Year(TheDate), TheDate)
Diff = DateDiff("d", Now(), TheDate)
If WithinDays >= 0 Then
IsAnniversary = Diff >= 0 And Diff <= WithinDays
Else
IsAnniversary = Diff <= 0 And Diff >= WithinDays
End If
End If
End Function
]]>
</msxsl:script>
</xsl:stylesheet>
The above quite well-tested and robust and it probably already does what you need(*), still you could re-implement the whole thing as a proper, XSLT-aware SharePoint extension based on the .NET Framework.
Here's an article on how to do that with respect to SharePoint: http://blog.mastykarz.nl/extending-content-query-web-part-xslt-custom-functions/ - it's from 2009 so it might not be a 100% fit with current versions of SharePoint, but it might start you off.
(*) I recommend you keep all your dates in ISO 8601 format (YYYY-MM-DD
) so that CDate()
recognizes them correctly.
Upvotes: 1