2010-10-07 17 views
8

Ist es möglich mit xslt ein Datumsfeld zu nehmen und N Tage davon zu subtrahieren? Wenn ja, kannst du mir bitte ein Beispiel geben?xslt - Subtrahieren von Tagen

+0

Welchen XSLT-Prozessor verwenden Sie? –

+0

XSLT 1.0 oder XSLT 2.0? Was ist das Datumsformat? –

+0

Gute Frage, +1. Sehen Sie meine Antwort für eine komplette XSLT 2.0 Lösung. –

Antwort

13

Hier ein Beispiel, wie diese 2.0 in XSLT zu tun:

<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> 

wenn diese Transformation auf jedem XML-Dokument (nicht benutzt) angewandt wird, die wollte, ist korrektes Ergebnis hergestellt:

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 
+0

+1 Gute Antwort! –

+0

FYI ... '' verursacht eine leere Seite in Firefox 25 und Chrome 30. Firefox gibt einen Konsolenfehler von 'Component retourned failure code: 0x80600005 [nsIXSLTProcessor.importStylesheet] '. Hoppla, anscheinend musst du 'version =" 2.0 "' in 'xsl: stylesheet' angeben. Ich habe Version 1.0 benutzt. – doubleJ

+0

FYI2 ... Auch wenn "version = 2.0" angegeben ist, erzeugt Chrome 30 eine leere Seite. Firefox 25 zeigt jedoch Ergebnisse. – doubleJ

1

Nun, XSLT kann Strings und Parse-Nummern teilen, also ja, es wäre "möglich".

Es wäre jedoch viel einfacher und effizienter, wenn Sie Erweiterungsfunktionen verwenden und das in einer anderen Sprache implementieren könnten. Ob und wie das funktioniert, hängt jedoch von der verwendeten XSLT-Engine ab.

EXSLT kann alles, was Sie brauchen haben: http://www.exslt.org/date/functions/add/index.html

5

Ja, mit XSLT 2.0 es möglich ist, und sehr einfach zu tun.

Es gibt viele Date/Time/Duration functions in XPATH 2.0, die Teil von XSLT 2.0 sind.

Dieses Beispiel subtrahiert 1 Tag ab dem Tag 2010-01-01 2009-12-31 zu produzieren:

<?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> 
-2
<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> 
0

Ich kann sehen, dass alle erwähnten Lösungen für XSLT 2.0 sind. Ich habe ähnliche Lösung für XSLT 1.0 mit EXSLT Datum:

Beispiel: Beachten Sie, dass die Anzahl der Tage zu subtrahieren ist 365 und wir brauchen es als Standard Startdatum. In diesem Fall müssen wir die Dauer 365 Tage im Format xs: dayTimeDuration angeben, d. H. "-P365D".

Hier finden Sie den Code.

<?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> 
+0

zu verwenden Leider unterstützen nur wenige XSLT 1.0-Prozessoren EXSLT 'date: add()'. Eine reine XSLT 1.0-Lösung ohne Erweiterungen finden Sie unter https://stackoverflow.com/questions/23566734/date-operations-on-xsl-1-0/23569278#23569278 –