xslt - вычитание дней - PullRequest
       6

xslt - вычитание дней

9 голосов
/ 07 октября 2010

Можно ли с помощью xslt взять поле даты и вычесть из него N дней?Если да, не могли бы вы привести пример?

Ответы [ 5 ]

16 голосов
/ 08 октября 2010

Вот демонстрация того, как сделать это в XSLT 2.0:

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

 <xsl:template match="/">
  <xsl:variable name="vToday" select="current-date()"/>

  Today is: <xsl:sequence select="$vToday"/>
  30 days ago it was: <xsl:sequence select=
    "$vToday -30*xs:dayTimeDuration('P1D')"/>
  365 days ago it was: <xsl:sequence select=
    "$vToday -365*xs:dayTimeDuration('P1D')"/>
 </xsl:template>
</xsl:stylesheet>

, когда это преобразование применяется к любому документу XML (не используется), получается требуемый, правильный результат :

  Today is: 2010-10-07-07:00
  30 days ago it was: 2010-09-07-07:00
  365 days ago it was: 2009-10-07-07:00
6 голосов
/ 08 октября 2010

Да, с XSLT 2.0 это возможно и очень просто сделать.

В XPATH 2.0 имеется множество функций Дата / Время / Продолжительность, которые являются частью XSLT 2.0 .

В этом примере вычитается 1 день с даты 2010-01-01 для производства 2009-12-31:

<?xml version="1.0"?>
<xsl:stylesheet version="2.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xsl:template match="/">
  <xsl:value-of select="xs:date('2010-01-01') - xs:dayTimeDuration('P1D')" />
</xsl:template>
</xsl:stylesheet>
1 голос
/ 23 мая 2017

Я вижу, что все упомянутые решения предназначены для XSLT 2.0.У меня есть аналогичное решение для XSLT 1.0 с использованием EXSLT date: add

Пример. Предположим, что число дней, которое нужно вычесть, равно 365, и нам нужно, чтобы это было начальная дата по умолчанию.В этом случае мы должны предоставить продолжительность 365 дней в формате xs: dayTimeDuration, то есть «-P365D».

Пожалуйста, найдите код ниже.

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:date="http://exslt.org/dates-and-times"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
extension-element-prefixes="date xs"
exclude-result-prefixes="date xs" version="1.0">
<xsl:output method="xml" version="1.0" encoding="UTF-8" />

    <xsl:template match="/">
      <xsl:variable name="vCurrDate" select="date:date-time()"/>
      <xsl:variable name="vDefaultStDate" select="(date:add($vCurrDate, '-P365D'))"/>
    </xsl:template>
</xsl:stylesheet>
1 голос
/ 07 октября 2010

Ну, XSLT может разбивать строки и разбирать номера, так что да, это было бы "возможно".

Однако было бы намного проще и эффективнее, если бы вы могли использовать функции расширения и реализовать это на другом языке. Однако, если и как это работает, зависит от используемого механизма XSLT.

EXSLT может иметь все необходимое: http://www.exslt.org/date/functions/add/index.html

0 голосов
/ 20 февраля 2014
<xsl:template name="dim" >

  <xsl:param name="y" />
  <xsl:param name="m"/>

  <xsl:choose>
     <xsl:when test="($m=1 or $m=3 or $m=5 or $m=7 or $m=8 or $m=10 or $m=12)" >
          31  
    </xsl:when>
    <xsl:when test="$m&gt;2">
         30 
   </xsl:when>
    <xsl:when test="($m=2) and (not($y mod 4=0)) or ($y mod 100=0) and (not($y mod 400=0))">
      28  
    </xsl:when>
    <xsl:otherwise>
       29
    </xsl:otherwise>
  </xsl:choose>

</xsl:template>


<xsl:template name="minusdays">
<xsl:param name="year" />
<xsl:param name="month" />
<xsl:param name="day"/>
<xsl:param name="days"/>
<xsl:variable name="lm" select="number($month)-1+number($month=1)*12"/>

<xsl:variable name="lmdays">
    <xsl:call-template name="dim">
       <xsl:with-param name="y" select="$year"/>
       <xsl:with-param name="m" select="$lm"/>
    </xsl:call-template>
</xsl:variable>

<xsl:choose>
    <xsl:when test="$days&lt;$day">
        <xsl:value-of select="$year"/>
       <xsl:if test="number($month)&lt;10">0</xsl:if>
       <xsl:value-of select="$month"/>
       <xsl:if test="($day - $days)&lt;10">0</xsl:if>
       <xsl:value-of select="$day - $days"/>
    </xsl:when>
    <xsl:otherwise>
        <xsl:call-template name="minusdays">
           <xsl:with-param name="year" 
           select="number($year)-number($month=1)"/>
         <xsl:with-param name="month" select="$lm" />
         <xsl:with-param name="day" select="$lmdays"/>
         <xsl:with-param name="days" select="$days - $day" />    
       </xsl:call-template>
    </xsl:otherwise>
</xsl:choose> 

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