xslt: тест времени назад - PullRequest
1 голос
/ 22 июля 2010

с использованием xslt. Как проверить, была ли дата в течение последних (скажем) 15 дней?

ввод:

  • дата в формате дд / мм / гг
  • X количество дней

выход:

  • если дата произошла в течение X дней с этого момента

например, недавний ('02 / 07/10 ', 30) вернул бы значение true, если бы 02/07/10 было 30 дней назад

несколько шагов, которые я получил:

основной функционал

    <xsl:function name="custom:monthtodays">
    <xsl:param name="date"/>
    <xsl:param name="daysago"/>
    <xsl:variable name="daycountnow" select="year-from-dateTime(current-dateTime())*365+day-from-dateTime(current-dateTime())+custom:monthtodays(month-from-dateTime(current-dateTime())" />
    <xsl:variable name="datedaycount" select="numeric(substring($date,1,2))+numeric(substring($date,7,2))*365+custom:monthtodays(numeric(substring($date,4,2)))" />
    <xsl:value-of select="$daycountnow - $datedaycount - $daysago > 0"/>
</xsl:function>

вспомогательная функция

 <xsl:function name="custom:monthtodays">
    <xsl:param name="month"/>
    <xsl:choose>
      <xsl:when test="$month =1"> <xsl:value-of select="0"/> </xsl:when>
      <xsl:when test="$month =2"> <xsl:value-of select="31"/> </xsl:when>
      <xsl:when test="$month =3"> <xsl:value-of select="59"/> </xsl:when>
      <xsl:when test="$month =4"> <xsl:value-of select="90"/> </xsl:when>
      <xsl:when test="$month =5"> <xsl:value-of select="120"/> </xsl:when>
      <xsl:when test="$month =6"> <xsl:value-of select="151"/> </xsl:when>
      <xsl:when test="$month =7"> <xsl:value-of select="181"/> </xsl:when>
      <xsl:when test="$month =8"> <xsl:value-of select="212"/> </xsl:when>
      <xsl:when test="$month =9"> <xsl:value-of select="243"/> </xsl:when>
      <xsl:when test="$month =10"> <xsl:value-of select="273"/> </xsl:when>
      <xsl:when test="$month =11"> <xsl:value-of select="304"/> </xsl:when>
      <xsl:when test="$month =12"> <xsl:value-of select="334"/> </xsl:when>
    </xsl:choose>
  </xsl:function>

но это не учитывает високосные годы и тому подобное ... конечно, есть лучший путь?

Ответы [ 2 ]

1 голос
/ 23 июля 2010

Вот один из способов сделать это в XSLT 1.0. Поскольку вы используете .Net 4.0, у вас должна быть возможность использовать функцию расширения Microsoft и написать собственную (javascript) функцию для изменения даты.

Вот трансформация. Обратите внимание, что функция JavaScript довольно грубая и предполагает дату в формате ДД / ММ / ГГ:

<?xml version='1.0'?> 
<xsl:stylesheet version="1.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:msxsl="urn:schemas-microsoft-com:xslt" 
    xmlns:user="http://mycompany.com/mynamespace"> 

<msxsl:script language="javascript" implements-prefix="user"> 
function datecheck(dateString)  
{ 
    // Get today's date
    var today = new Date();

    // Clear down any time portion
    today.setHours(0);
    today.setMinutes(0);
    today.setSeconds(0);
    today.setMilliseconds(0);

    // Length of day in milliseconds
    var one_day = 1000*60*60*24;

    // Convert date string into a date
    var day = parseInt(dateString.substring(0, 2), 10);
    var month = parseInt(dateString.substr(3, 2), 10);
    var year = 2000 + parseInt(dateString.substr(6, 2), 10);
    var date = new Date(year, month - 1, day);

    // Get date difference
    var diff = Math.ceil((today.getTime()-date.getTime()) / one_day);
    return (diff &lt;= 30);
} 
</msxsl:script> 

<xsl:template match="/*"> 
   <xsl:value-of select="user:datecheck(string(.))"/> 
</xsl:template> 

</xsl:stylesheet> 

Когда вы применяете его к этому входу (предполагая, что сегодня 23/07/2010)

<date>02/07/10</date> 

Вы должны получить возвращаемое значение true

Когда вы применяете его к этому входу

<date>02/06/10</date> 

Вы должны получить возвращаемое значение false

1 голос
/ 22 июля 2010

Это преобразование :

<xsl:stylesheet version="2.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    xmlns:my="my:my">

  <xsl:output method="text"/>

  <xsl:template match="/">
   <xsl:value-of select="my:isWithinDays(/*, 30)"/>
  </xsl:template>

  <xsl:function name="my:isWithinDays" as="xs:boolean">
   <xsl:param name="pDate" as="xs:string"/>
   <xsl:param name="pDaysDuration" as="xs:integer"/>

    <xsl:variable name="vvalidDate" select=
     "concat('20',
             substring($pDate,7),
             '-',
             substring($pDate,4,2),
             '-',
             substring($pDate,1,2))"/>

     <xsl:sequence select=
      "current-date() - xs:date($vvalidDate) 
      le 
       xs:dayTimeDuration(concat('P',$pDaysDuration, 'D'))"/>
  </xsl:function>
</xsl:stylesheet>

при применении к этому документу XML :

<t>02/07/10</t>

дает желаемый результат :

true

При применении к этому документу XML :

<t>20/06/10</t>

снова получается правильный результат :

false

Примечание : это преобразование было выполнено сегодня, 21/07/10.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...