Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

XSLT transformation datetime to date format

Tags:

.net

xslt

xsd

I'm trying to transform a datetime to a date format yyyy-MM-dd, because I'm using the xsd.exe tool the xs:date datatypes are automatically changed into a datetime datatype, because there is no type in the .NET Framework that matches the type xs:date completely.

But I can't get it to work

<articles>
        <article>
          <articleid>48992</articleid>
          <deliverydateasked>2009-01-29T00:00:00+01:00</deliverydateasked>
        </article>
        <article>
          <articleid>48993</articleid>
          <deliverydateasked>2009-01-30T00:00:00+01:00</deliverydateasked>
        </article>
</articles>

trying to convert the xml to

<articles>
        <article>
          <articleid>48992</articleid>
          <deliverydateasked>2009-01-29</deliverydateasked>
        </article>
        <article>
          <articleid>48993</articleid>
          <deliverydateasked>2009-01-30</deliverydateasked>
        </article>
</articles>

currently I'm using this XSLT

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:template match="/">
    <articles>
        <xsl:apply-templates select="article">
        </xsl:apply-templates>
            </articles>
</xsl:template>

<xsl:template name="FormatDate">

    <xsl:param name="DateTime" />
    <xsl:variable name="date">
        <xsl:value-of select="substring-before($DateTime,'T')" />
    </xsl:variable>

    <xsl:if test="string-length($date) != 10">
        <xsl:value-of select="$DateTime"/>
    </xsl:if>
    <xsl:if test="string-length($date) = 10">
        <xsl:value-of select="$date"/>
    </xsl:if>
</xsl:template>

<xsl:template match="article">
        <xsl:call-template name="FormatDate">
            <xsl:with-param name="DateTime" select="deliverydateasked"/>
        </xsl:call-template>    
</xsl:template>     

Does anyone know a good xslt transformation.

Thanks in advance

The output result of my code is

<articles /> 
like image 596
freggel Avatar asked Jan 28 '09 14:01

freggel


People also ask

How can I change the date format in XML?

Can use the following conversion code to convert UTC format string to any other DateTime format. string result = Convert. ToDateTime("2011-02-04T00:00:00+05:30"). ToString("MM/dd/yyyy h:mm:ss tt");

How do I change timezone in XSLT?

Using the xslt funtion adjust-dateTime-to-timezone($utc-timestamp, xs:dayTimeDuration('PT2H') this is not a problem but the conversion must be dynamic based on the TZ information from the source file (mainly Java TZs).

How do I replace in XSLT?

XSLT replace is deterministic and does string manipulation that replaces a sequence of characters defined inside a string that matches an expression. In simple terms, it does string substitution in the specified place by replacing any substrings. Fn: replace function is not available in XSLT1.


2 Answers

Formatting will get a lot easier in XPath 2.0, which Microsoft has currently refused to support for the last 8 years. Since the formatting issue is really only persistent for XSLT in .Net I like to use a custom function, which is cleaner & easier:

XSLT With Formatting Function:

    xmlns="http://www.w3.org/1999/xhtml"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:msxsl="urn:schemas-microsoft-com:xslt"
    xmlns:user="http://www.tempuri.org/User">

  <msxsl:script implements-prefix="user" language="C#">
        <![CDATA[
          public string FormatCurrency(string amount)
          {
            return decimal.Parse(amount).ToString("C0");
          }

          public string FormatDate(string dateValue)
          {
            return DateTime.Parse(dateValue).ToString("MM/dd/yyyy hh:mm");
          }
          ]]>
      </msxsl:script>

Usage:

<xsl:value-of select="user:FormatDate(@transactionDate)"/>
<xsl:value-of select="user:FormatCurrency(@amount)"/>

When you execute your XSLT in .Net make sure to tell it that it's trusted (so that the msxsl:script block will run.

XslCompiledTransform.Load(reader, XsltSettings.TrustedXslt, null);
like image 79
Scott White Avatar answered Oct 12 '22 23:10

Scott White


Frankly, this looks about right to me - sometimes a simple substring is good enough.

However, if you're in .NET land and you're really needing extra functionality .NET has XSLT Extension Objects


edit: oic, you've got a basic apply-templates conceptual problem. Try this (note the copy and the root template match):

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">

<xsl:template match="*">
    <xsl:copy><xsl:apply-templates /></xsl:copy>
</xsl:template>

<xsl:template match="deliverydateasked">
    <xsl:copy>
        <xsl:call-template name="FormatDate">
            <xsl:with-param name="DateTime" select="."/>
        </xsl:call-template>    
    </xsl:copy>
</xsl:template>

<xsl:template name="FormatDate">

        <xsl:param name="DateTime" />
        <xsl:variable name="date">
                <xsl:value-of select="substring-before($DateTime,'T')" />
        </xsl:variable>

        <xsl:if test="string-length($date) != 10">
                <xsl:value-of select="$DateTime"/>
        </xsl:if>
        <xsl:if test="string-length($date) = 10">
                <xsl:value-of select="$date"/>
        </xsl:if>
</xsl:template>

</xsl:stylesheet>

templates is a hard concept to learn, you might be better off starting with the more straightforward for-each, and/or it seems you could do with some XSLT tutorials/books.

like image 30
annakata Avatar answered Oct 13 '22 00:10

annakata