Можно ли с xslt взять поле даты и вычесть из него N дней? Если да, можете ли вы привести мне пример?
Xslt - вычитание дней
Ответ 1
Вот демонстрация, как это сделать в 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
Ответ 2
Да, с XSLT 2.0 можно и очень легко сделать.
В XPATH 2.0 существует множество функций Date/Time/Duration, которые являются частью 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>
Ответ 3
Ну, XSLT может разделить строки и номера синтаксического анализа, так что да, это было бы "возможно".
Однако было бы намного проще и эффективнее, если бы вы могли использовать функции расширения и реализовать это на другом языке. Однако, если и как это работает, зависит от используемого движка XSLT.
EXSLT может иметь все, что вам нужно: http://www.exslt.org/date/functions/add/index.html
Ответ 4
Я вижу, что все упомянутые решения для 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>
Ответ 5
<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>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<$day">
<xsl:value-of select="$year"/>
<xsl:if test="number($month)<10">0</xsl:if>
<xsl:value-of select="$month"/>
<xsl:if test="($day - $days)<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>