سؤال

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))))
&gt;= (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))))
&lt;= (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.

هل كانت مفيدة؟

المحلول

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.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top