tags:

views:

259

answers:

4

I’m working on a site In that site some pages gets data from XML through XSLT. But the date is displayed as YYYY-MM-DD which ideally is taken from the XML which was in this format. I would like to convert this format to DD-MM-YYYY through XSLT or some other possible way.

Please suggest me an idea to go ahead or provide me the code to achieve this ASAP. This is the format of xml giving

 <published date="2009-09-28T07:06:00 CET" />

and i want to convert this into

 <published date="28-09-2009T07:06:00 CET" />

and this is xsl file

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"&gt;
  <xsl:template match="/">
    <html>
      <body>
        <table class="bdr-bot" width="100%" border="0" cellspacing="0" cellpadding="0" style="clear:both">
          <tr>
            <th width="15%" class="bdr">Date</th>
            <th class="bdr">Title</th>
          </tr>
          <xsl:for-each select="hexML/body/press_releases/press_release">
          <xsl:if test="contains(published/@date, '2009')">
            <tr>
              <td valign="top">
                <xsl:value-of select="substring-before(published/@date, 'T')"/>
              </td>
              <td valign="top">
              <a href="result-page.aspx?ResultPageURL={location/@href}"><xsl:value-of select="headline"/></a>
              </td>
            </tr>
            </xsl:if>
          </xsl:for-each>
        </table>
      </body>
    </html>
  </xsl:template>

Now tell me the solution? is this possible with fn:reverse?

+2  A: 

If the XML is in the format YYYY-MM-DD, you should be able to use Xpath's tokenize function to split up your string where - occurs, and then reorder it. Something akin to:

<xsl:variable name="dt" value="tokenize(Date, '-')"/>
<xsl:value-of select="concat(dt[3],'-',dt[2],'-',dt[1])"/>

This is just off the top of my head (and untested), but you get the general idea. You should be able to split up the date and reorder the pieces.

Jweede
+1  A: 

you could also use a template.

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

    <html>
      <body>
        <table class="bdr-bot" width="100%" border="0" cellspacing="0" cellpadding="0" style="clear:both">
          <tr>
            <th width="15%" class="bdr">Date</th>
            <th class="bdr">Title</th>
          </tr>
         <!-- <xsl:for-each select="hexML/body/press_releases/press_release">-->
            <xsl:if test="contains(published/@date, '2009')">
              <tr>
                <td valign="top">
                  <xsl:call-template name="FormatDate">
                    <xsl:with-param name="DateTime" select="published/@date"/>
                  </xsl:call-template>
                </td>
                  <td valign="top">
                  <a href="result-page.aspx?ResultPageURL={location/@href}">
                    <xsl:value-of select="headline"/>
                  </a>
                </td>
              </tr>
            </xsl:if>
          <!--</xsl:for-each>-->
        </table>
      </body>
    </html>
  </xsl:template>
  <xsl:template name="FormatDate">
    <xsl:param name="DateTime"/>
        <xsl:value-of select="substring($DateTime,9,2)"/>-<xsl:value-of select="substring($DateTime,6,2)"/>-<xsl:value-of select="substring($DateTime,1,4)"/><xsl:text> CET</xsl:text>
  </xsl:template>
</xsl:stylesheet>
Pharabus
i added more info to question
metal-gear-solid
how can i set ur solution in my template?
metal-gear-solid
I edited to more reflect your current xslt and the xml, I coomented out the loop as it was easier for me without you full xml but it should work, also I have assumed the CET is constant, if not you can add another substring for the last 3 characters.
Pharabus
is it also possible with fn:reverse?
metal-gear-solid
it would probably be a little difficult, you would need to strip out the unused data like the time first and the time zone to just revers the date part of the string and then re-add the bit you needed like the timezone. I haven't really used that function in anger so maybe someone else would now in better detail
Pharabus
only because I didnt have the full XML to hand, you can fit it back in easily
Pharabus
+1  A: 

Assuming

<xml>
  <date>2009-11-18</date>
</xml>

This XSLT 1.0 solution would do it:

<xsl:template match="date">
  <xsl:copy>
    <xsl:value-of select="
      concat(
        substring(., 9, 2),
        '-',
        substring(., 6, 2),
        '-',
        substring(., 1, 4)
      )
    " />
  </xsl:copy>
</xsl:template>

If your date can be

<xml>
  <date>2009-11-1</date>
</xml>

you would have to use the slightly more complicated

<xsl:template match="date">
  <xsl:copy>
    <xsl:value-of select="
      concat(
        substring-after(substring-after(., '-'), '-'), 
        '-',
        substring-before(substring-after(., '-'), '-'), 
        '-',
        substring-before(., '-')
      )
    " />
  </xsl:copy>
</xsl:template>
Tomalak
A: 

It appears that you need to use an XSLT 2.0 schema aware processor to get built-in support for what you want to do with the xs:dateTime data type and the format-date function.

See http://www.w3.org/TR/xmlschema-2/#dateTime for the requirements for XSLT 2.0 being able to parse the string you have.

The ·lexical space· of dateTime consists of finite-length sequences of characters of the form: '-'? yyyy '-' mm '-' dd 'T' hh ':' mm ':' ss ('.' s+)? (zzzzzz)?

See http://www.dpawson.co.uk/xsl/rev2/dates.html#d16685e16 for generating output.

format-date( xs:date( concat( substring($d,1,4), '-', substring($d,7,2), '-', substring($d,5,2))), '[D01] [MNn] [Y0001]')

Thorbjørn Ravn Andersen