?
Solved

XSL Date's

Posted on 2003-02-27
4
Medium Priority
?
559 Views
Last Modified: 2011-09-20
Hello, i have a CD database that is exporting its data do XML, and i'm using XSL to transform it to HTML so i can publish it on the web.

There is a field that is the "PURCHASEDATE", what i'm trying to do is : when this purchase date is superior to the actual date minus two months i want to display an image like "new.gif" next to the name of the album for example, is this possible ?

sample XML :

<ROOT>
   <ITEM>
        <TITLE>something</TITLE>
        <PURCHASEDATE>2002-12-18</PURCHASEDATE>
   </ITEM>
   <ITEM>
        <TITLE>something2</TITLE>
        <PURCHASEDATE>2003-02-12</PURCHASEDATE>
   </ITEM>
</ROOT>

In this case only "something2" should have the new.gif image next to it.

Thanks in advance.
0
Comment
Question by:PauloFernandes
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
4 Comments
 
LVL 6

Accepted Solution

by:
Wayne Bradney earned 100 total points
ID: 8037056
PauloFernandes,

The more complex data types like dates that require non-trivial arithmetic to manipulate them are, unfortunately not very easy to handle directly in XSL. Not least of your problems is that you need access to today's date - which is not directly available to the transformation engine with any standard XSL construct. As I see it you have a couple of options:

1. Arrange for the XML to be generated including today's date (ie. the date on which the XML was generated). eg:

<ROOT genereatedAt="2003-02-27">
...

This will allow you to use some (messy) xsl directly in the stylesheet to figure out newness, something like this:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                version="1.0">
  <xsl:output method="html"/>
  <xsl:template match="ROOT">
    <HTML>
    <BODY>
    <TABLE>
      <xsl:for-each select="ITEM">
        <TR>
       <TD>
            <xsl:call-template name="isNew">
              <xsl:with-param name="date">
                <xsl:value-of select="PURCHASEDATE"/>
              </xsl:with-param>
              <xsl:with-param name="today">
                <xsl:value-of select="/ROOT/@generatedAt"/>
              </xsl:with-param>
            </xsl:call-template>
          </TD>
          <TD><xsl:value-of select="TITLE"/></TD>
        </TR>
      </xsl:for-each>
    </TABLE>
    </BODY>
    </HTML>
  </xsl:template>

  <xsl:template name="isNew">
    <xsl:param name="date"/>
    <xsl:param name="today"/>
    <xsl:variable name="months" select="(substring-before($date, '-')-2000)*12+substring-before(substring-after($date, '-'), '-')"/>
    <xsl:variable name="todaymonths" select="(substring-before($today, '-')-2000)*12+substring-before(substring-after($today, '-'), '-')"/>
    <xsl:choose>
      <xsl:when test="($todaymonths - $months) = 2">
        <xsl:if test="substring-after($today, '-') &lt; substring-after($months, '-')">... output whatever indicator you like here ...</xsl:if>
      </xsl:when>
      <xsl:when test="($todaymonths - $months) &lt; 3">... output whatever indicator you like here ...</xsl:when>
    </xsl:choose>
  </xsl:template>
</xsl:stylesheet>

Note that this assumes that your dates are in a specific format (ISO CCYY-MM-DD), and that you're actually generating the XML with some program that has access to the system date (ie not manually maintained).

2. If you have access to a JVM, you could use XSL Extensions, which would clean up the XSL considerably:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:java="http://xml.apache.org/xslt/java"
                exclude-result-prefixes="java"
                version="1.0">
  <xsl:output method="html"/>
  <xsl:template match="ROOT">
    <HTML>
    <BODY>
    <TABLE>
      <xsl:for-each select="ITEM">
        <TR>
          <TD>
            <xsl:variable name="dt" select="PURCHASEDATE"/>
            <xsl:variable name="isNew" select="java:MyDateUtilities.isNew(string($dt))"/>
            <xsl:if test="$isNew = 1">... output whatever indicator you like here ...</xsl:if>
          </TD>
          <TD><xsl:value-of select="TITLE"/></TD>
        </TR>
      </xsl:for-each>
    </TABLE>
    </BODY>
    </HTML>
  </xsl:template>
</xsl:stylesheet>

Then you'd write a class called MyDateUtilities with a method is New that does the heavy lifting of date manipulation. Note that this solution also allows you to centralise the decision of what's "New": you don't have to wade through the XSL to changed from two months to three months when you change your mind. The Java class could even read this parameter from an application property file, and your XSL remains static.

Regards,
WMB
0
 
LVL 3

Assisted Solution

by:DitmarBehn
DitmarBehn earned 100 total points
ID: 8040024
Hi Paulo,

if you are using the MSXML parser from Microsoft you might try the following code to build the current system date. It is a JavaScript routine, embedded in the proprietary MS extension 'msxsl:script':

<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0"
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:user="http://myURL.com"
                xmlns:msxsl="urn:schemas-microsoft-com:xslt"
                >
  <!-- Output should be HTML -->
  <xsl:output method="html" encoding="ISO-8859-1" />

  <!-- Scripting block, available at transformation time -->
  <msxsl:script language="JavaScript" implements-prefix="user">
  <![CDATA[
       function getDate() {
            var d = new Date();
      var strReturnValue = d.getYear()+ "-";
      strReturnValue += (d.getMonth() + 1) + "-";
      strReturnValue += d.getDate();

         return strReturnValue;
       }
  ]]>
  </msxsl:script>
 
  <!-- Put the date into a variable  -->
  <xsl:variable name="myDate">
    <xsl:value-of select="user:getDate()"/>
  </xsl:variable>

  <!-- Just process the root, all other iterations will be performed explicitly -->
  <xsl:template match="/">
    <html>
      <body>
        <!-- with all distinct values of the subtree nodes -->
        <xsl:for-each select="/ROOT/ITEM">
          <!-- Print out the title -->
          <xsl:value-of select="TITLE/text()" />

          <!-- Determine whether Date matches -->
          <xsl:choose>
            <xsl:when test="PURCHASEDATE/text() = $myDate">
              <!-- and take some action (to be enhanced :-)) -->
              <xsl:value-of select="'Date matches'" />
            </xsl:when>
            <xsl:otherwise>
              <!-- resp. -->
              <xsl:value-of select="'Date does not match'" />
            </xsl:otherwise>
          </xsl:choose>

        </xsl:for-each>
      </body>
    </html>
  </xsl:template>

</xsl:stylesheet>

HTH, Ditmar

====================================================
Ditmar Behn
Managing Consultant
Itelligence AG
Germany
Ditmar.Behn@itelligence.de
====================================================
0

Featured Post

Free Tool: ZipGrep

ZipGrep is a utility that can list and search zip (.war, .ear, .jar, etc) archives for text patterns, without the need to extract the archive's contents.

One of a set of tools we're offering as a way to say thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

The Client Need Led Us to RSS I recently had an investment company ask me how they might notify their constituents about their newsworthy publications.  Probably you would think "Facebook" or "Twitter" but this is an interesting client.  Their cons…
I was working on a PowerPoint add-in the other day and a client asked me "can you implement a feature which processes a chart when it's pasted into a slide from another deck?". It got me wondering how to hook into built-in ribbon events in Office.
In this brief tutorial Pawel from AdRem Software explains how you can quickly find out which services are running on your network, or what are the IP addresses of servers responsible for each service. Software used is freeware NetCrunch Tools (https…
This is my first video review of Microsoft Bookings, I will be doing a part two with a bit more information, but wanted to get this out to you folks.
Suggested Courses

771 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question