Want to protect your cyber security and still get fast solutions? Ask a secure question today.Go Premium

x
?
Solved

XSL Date's

Posted on 2003-02-27
4
Medium Priority
?
562 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
2 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

[Webinar On Demand] Database Backup and Recovery

Does your company store data on premises, off site, in the cloud, or a combination of these? If you answered “yes”, you need a data backup recovery plan that fits each and every platform. Watch now as as Percona teaches us how to build agile data backup recovery plan.

Question has a verified solution.

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

The Problem How to write an Xquery that works like a SQL outer join, providing placeholders for absent data on the outer side?  I give a bit more background at the end. The situation expressed as relational data Let’s work through this.  I’ve …
Introduction In my previous article (http://www.experts-exchange.com/Microsoft/Development/MS-SQL-Server/SSIS/A_9150-Loading-XML-Using-SSIS.html) I showed you how the XML Source component can be used to load XML files into a SQL Server database, us…
This lesson discusses how to use a Mainform + Subforms in Microsoft Access to find and enter data for payments on orders. The sample data comes from a custom shop that builds and sells movable storage structures that are delivered to your property. …
Kernel Data Recovery is a renowned Data Recovery solution provider which offers wide range of softwares for both enterprise and home users with its cost-effective solutions. Let's have a quick overview of the journey and data recovery tools range he…
Suggested Courses

580 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