Formatowanie daty w XML przez XSLT

Kiedy używam serializera XML do serializacji DateTime, jest on zapisywany w następującym formacie:

<Date>2007-11-14T12:01:00</Date>

Jak sformatować to w arkuszu stylów XSLT do wyjścia HTML? W większości przypadków potrzebuję tylko daty, a kiedy potrzebuję czasu, oczywiście nie chcę tam "funny T".

Author: Rui Jarimba, 2009-02-01

6 answers

Oto kilka szablonów 1.0, których możesz użyć:-

<xsl:template name="formatDate">
    <xsl:param name="dateTime" />
    <xsl:variable name="date" select="substring-before($dateTime, 'T')" />
    <xsl:variable name="year" select="substring-before($date, '-')" />
    <xsl:variable name="month" select="substring-before(substring-after($date, '-'), '-')" />
    <xsl:variable name="day" select="substring-after(substring-after($date, '-'), '-')" />
    <xsl:value-of select="concat($day, ' ', $month, ' ', $year)" />
</xsl:template>

<xsl:template name="formatTime">
    <xsl:param name="dateTime" />
    <xsl:value-of select="substring-after($dateTime, 'T')" />
</xsl:template>

Wywołaj je przez:-

    <xsl:call-template name="formatDate">
        <xsl:with-param name="dateTime" select="xpath" />
    </xsl:call-template>

I

    <xsl:call-template name="formatTime">
        <xsl:with-param name="dateTime" select="xpath" />
    </xsl:call-template>

Gdzie xpath jest ścieżką do elementu lub atrybutu, który ma standardowy format daty i czasu.

 66
Author: AnthonyWJones,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-02-01 15:01:35

Formatowanie daty nie jest łatwe w XSLT 1.0. Prawdopodobnie najbardziej eleganckim sposobem jest napisanie krótkiej funkcji rozszerzenia XSLT w C# do formatowania dat. Oto przykład:

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"
                xmlns:msxsl="urn:schemas-microsoft-com:xslt"
                xmlns:myExtension="urn:myExtension"
                exclude-result-prefixes="msxsl myExtension">
  <xsl:output method="xml" indent="yes"/>

  <msxsl:script implements-prefix="myExtension" language="C#">
    <![CDATA[
      public string FormatDateTime(string xsdDateTime, string format)
      {
          DateTime date = DateTime.Parse(xsdDateTime);
          return date.ToString(format); 
      }

    ]]>
  </msxsl:script>

  <xsl:template match="date">
    <formattedDate>
      <xsl:value-of select="myExtension:FormatDateTime(self::node(), 'd')"/>
    </formattedDate>
  </xsl:template>
</xsl:stylesheet>

Z tym dokumentem wejściowym

<?xml version="1.0" encoding="utf-8"?>
<date>2007-11-14T12:01:00</date>

Dostaniesz

<?xml version="1.0" encoding="utf-8"?>
<formattedDate>14.11.2007</formattedDate> 

Funkcja formatująca datę przyjmuje wartość daty jako łańcuch znaków i format opisany w DateTime.Metoda ToString . Korzystanie z struktury DateTime. NET daje parsowanie dowolnych wartości datetime XSD (w tym strefy czasowej specyfikatorów), Obliczanie strefy czasowej i zlokalizowane wyjście za darmo.

Należy jednak pamiętać, że istnieje jedno zastrzeżenie (http://support.microsoft.com/kb/316775) z rozszerzeniami skryptów msxml: za każdym razem, gdy ładujesz XSLT, Zgromadzenie zawierające kod skryptu jest generowane dynamicznie i ładowane do pamięci. Ze względu na konstrukcję środowiska uruchomieniowego.NET, tego zestawu nie można rozładować. Dlatego musisz się upewnić, że Twój XSLT jest ładowany tylko raz (a następnie buforowany do dalszego ponownego użycia). Jest to szczególnie ważne podczas uruchamiania wewnątrz IIS.

 25
Author: Dirk Vollmar,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-02-01 15:16:12

John Workman omawia ten problem obszernie i podaje kilka rozwiązań w tej dyskusji [1] na swoim blogu. Zasadniczo analizuj poszczególne składniki daty i rekombinuj w dowolnej kolejności. W Twoim przypadku czysta wersja XSLT 1.0+ byłaby:

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="date">
<!-- converts FROM <date>2001-12-31T12:00:00</date> TO some new format (DEFINED below) -->
<xsl:template name="FormatDate">
<xsl:param name="DateTime" />

<xsl:variable name="year" select="substring($DateTime,1,4)" />
<xsl:variable name="month-temp" select="substring-after($DateTime,'-')" />
<xsl:variable name="month" select="substring-before($month-temp,'-')" />
<xsl:variable name="day-temp" select="substring-after($month-temp,'-')" />
<xsl:variable name="day" select="substring($day-temp,1,2)" />
<xsl:variable name="time" select="substring-after($DateTime,'T')" />
<xsl:variable name="hh" select="substring($time,1,2)" />
<xsl:variable name="mm" select="substring($time,4,2)" />
<xsl:variable name="ss" select="substring($time,7,2)" />

<!-- EUROPEAN FORMAT -->
<xsl:value-of select="$day"/>
<xsl:value-of select="'.'"/> <!--18.-->
<xsl:value-of select="$month"/>
<xsl:value-of select="'.'"/> <!--18.03.-->
<xsl:value-of select="$year"/>
<xsl:value-of select="' '"/> <!--18.03.1976 -->
<xsl:value-of select="$hh"/>
<xsl:value-of select="':'"/> <!--18.03.1976 13: -->
<xsl:value-of select="$mm"/>
<xsl:value-of select="':'"/> <!--18.03.1976 13:24 -->
<xsl:value-of select="$ss"/> <!--18.03.1976 13:24:55 -->
<!-- END: EUROPEAN FORMAT -->

</xsl:template>

Inny format (zastępuje sekcję formatu Europejskiego):

<!-- Long DATE FORMAT -->
<xsl:choose>
<xsl:when test="$month = '1' or $month= '01'">January</xsl:when>
<xsl:when test="$month = '2' or $month= '02'">February</xsl:when>
<xsl:when test="$month= '3' or $month= '03'">March</xsl:when>
<xsl:when test="$month= '4' or $month= '04'">April</xsl:when>
<xsl:when test="$month= '5' or $month= '05'">May</xsl:when>
<xsl:when test="$month= '6' or $month= '06'">June</xsl:when>
<xsl:when test="$month= '7' or $month= '07'">July</xsl:when>
<xsl:when test="$month= '8' or $month= '08'">August</xsl:when>
<xsl:when test="$month= '9' or $month= '09'">September</xsl:when>
<xsl:when test="$month= '10'">October</xsl:when>
<xsl:when test="$month= '11'">November</xsl:when>
<xsl:when test="$month= '12'">December</xsl:when>
</xsl:choose> 
<xsl:value-of select="' '"/> <!--January -->
<xsl:value-of select="$day"/> <!--January 12 -->
<xsl:value-of select="','"/> <!--January 12,-->
<xsl:value-of select="' '"/> <!--January 12, -->
<xsl:value-of select="$year"/> <!--January 12, 2001-->
<!-- END: Long DATE FORMAT -->
Możesz rekombinować elementy w dowolny sposób.

[1] http://geekswithblogs.net/workdog/archive/2007/02/08/105858.aspx @@ http://archive.is/4Hjep

 9
Author: rivy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-08-20 01:20:48

Przepraszam za komentowanie tego starego wątku, ale dla innych, którzy go znaleźli, jak ja, Możesz również użyć javascript, jeśli używasz ms transformer:

Zadeklaruj przestrzeń nazw "msxsl":

xmlns:msxsl="urn:schemas-microsoft-com:xslt" 

Zadeklaruj przestrzeń nazw dla skryptu:

xmlns:js="urn:custom-javascript" 

(opcjonalne) Pomiń prefiksy z wyjścia:

exclude-result-prefixes="msxsl js" 

Więc kończysz z deklaracją xsl taką jak ta:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"
  xmlns:msxsl="urn:schemas-microsoft-com:xslt"
  xmlns:js="urn:custom-javascript"
  exclude-result-prefixes="msxsl js">

Zapisz JavaScript w elemencie msxsl:script:

<msxsl:script language="JavaScript" implements-prefix="js"> 
<![CDATA[ 
function javascriptFunction(dateValue){
  var date = new Date(dateValue);
  if(!isNaN(date)) return date.toLocaleString();
  return dateValue;
}
]]>
</msxsl:script>

Call your JavaScript function (using the XPath syntax '."oznaczanie" tego węzła"):

<xsl:value-of select="js:javascriptFunction(string(.))"/>

NB: w momencie pisania nie wydaje się być (xsl)sposobem na dołączenie zewnętrznych plików js (np. biblioteka jquery). Można to zrobić, analizując stronę serwera plików xsl przed transformacją i dodając zawartość pliku js jako ciąg znaków do sekcji CDATA. Sam zacząłem tę trasę schodzić, ale doszedłem do wniosku, że jeśli potrzebujesz tego poziomu funkcjonalności, może lepiej umieścić ją w innej części rurociąg.

Źródło: http://dev.ektron.com/kb_article.aspx?id=482
ref: http://www.ibm.com/developerworks/xml/library/x-tipxsltjs/index.html

 5
Author: Phileas Fogg,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-04-14 14:53:08

Korekta do posta Roya: dzień z funkcji zawsze otrzyma wartość miesiąca. Użyj następującego wzoru:

<xsl:variable name="year" select="substring($dateTime,1,4)" />
<xsl:variable name="month-temp" select="substring-after($dateTime,'-')" />
<xsl:variable name="month" select="substring-before($month-temp,'-')" />
<xsl:variable name="day-temp" select="substring-after($month-temp,'-')" />
<xsl:variable name="day" select="substring($day-temp,1,2)" />
<xsl:variable name="time" select="substring-after($dateTime,'T')" />
<xsl:variable name="hh" select="substring($time,1,2)" />
<xsl:variable name="mm" select="substring($time,4,2)" />
<xsl:variable name="ss" select="substring($time,7,2)" />

<xsl:value-of select="concat($month,'/',$day,'/',$year,' ',$hh,':',$mm,':',$ss)" />

 3
Author: Andy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-11-24 17:31:28

Dzięki, ten post bardzo pomógł.

Zmieniałem kanał RSS, który używa następującego formatu daty: Mon, 04 Apr 2011 23:18:00 -0700. Oto nazwany szablon, którego użyłem do analizy.

<!--Parse date format: Mon, 04 Apr 2011 23:18:00 -0700-->
<xsl:template name="formatDate">

    <xsl:param name="dateIn" />

    <xsl:variable name="day" select="substring($dateIn, 0, 3)" />
    <xsl:variable name="date" select="substring($dateIn, 6, 2)" />
    <xsl:variable name="month" select="substring($dateIn, 9, 3)" />
    <xsl:variable name="year" select="substring($dateIn, 13, 4)" />

    <xsl:variable name="hour" select="substring($dateIn, 18, 2)" />
    <xsl:variable name="min" select="substring($dateIn, 21, 2)" />
    <xsl:variable name="sec" select="substring($dateIn, 24, 2)" />

    <xsl:value-of select="concat($date, ' ', $month, ' ', $year, ' ', $hour, ':', $min, ':', $sec)" />

</xsl:template>
 3
Author: Jibran,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-04-05 22:25:20