tags:

views:

384

answers:

3

I have to include a C# script in my XSLT file .. So as to calculate the difference between two dateTime values(and add it to some other values) .. I need to accept all the possible formats of date .. I was suppose to do it with XSLT .. but as XSLT doesn't allow to do it (implicitely) .. I found this remedy of calling a C# script .. I have to call that XSL transformation from many different C# programs .. so It would be painful (rather impossible) to write this code in all calling C# code .. :( Can you find some remedy for this

This is the XSLT code ..

 <xsl:variable name="date1" select="//date1"/>
  <xsl:variable name="date2" select="//date2"/>
  <msxsl:script language="C#" implements-prefix="cs">
    <![CDATA[

    private static string[] formats = new string[]
    {
        "MM/dd/yyyy HH:mm:ss tt",
        "MM/dd/yyyy HH:mm:ss",
        "MM/dd/yyyy H:mm:ss tt",
        "MM/dd/yyyy H:mm:ss",
"M/dd/yyyy HH:mm:ss tt",
"M/dd/yyyy HH:mm:ss",
"M/dd/yyyy H:mm:ss tt",
"M/dd/yyyy H:mm:ss",
"MM/d/yyyy HH:mm:ss tt",
"MM/d/yyyy HH:mm:ss",
"MM/d/yyyy H:mm:ss tt",
"MM/d/yyyy H:mm:ss", 
"M/d/yyyy HH:mm:ss tt",   
"M/d/yyyy HH:mm:ss", 
"M/d/yyyy H:mm:ss tt", 
"M/d/yyyy H:mm:ss",      
    };


      public string datedif(string date1, string date2) {


            DateTime startTime;
            DateTime endTime;
            DateTime ThirdDate;

string date3="12/12/2009 00:00:00";

            DateTime.TryParseExact(date1, formats, new CultureInfo("en-US"), 
                                   DateTimeStyles.None, out startTime);
            DateTime.TryParseExact(date2, formats, new CultureInfo("en-US"), 
                                   DateTimeStyles.None, out endTime);
            DateTime.TryParseExact(date3, formats, new CultureInfo("en-US"), 
                                   DateTimeStyles.None, out ThirdDate);

ThirdDate = ThirdDate.Add(endTime.Subtract(startTime));


string result = ThirdDate.ToString("MM'/'dd'/'yyyy' 'HH':'mm':'ss");
return(result);

         }
     ]]>
  </msxsl:script>
  <xsl:template match="datediff">
    <xsl:element name="{local-name()}">
      <xsl:value-of select="cs:datedif($date1, $date2)" />
    </xsl:element>
  </xsl:template>

and the errors are :

  1. The name 'DateTimeStyles' does not exist in the current context

  2. The type or namespace name 'CultureInfo' could not be found (are you missing a using directive or an assembly reference?)

ThanQ very much .. Jon Skeet

+5  A: 

Those are errors from the C# compiler. You need to give a lot more information on what you're trying to do.

It sounds like you're at least missing a using directive of:

using System.Globalization;

but you haven't said where the errors are or what you're doing.

EDIT: If you can't change anything else, then change the references to DateTimeStyles and CultureInfo to be fully qualified:

global::System.Globalization.DateTimeStyles
global::System.Globalization.CultureInfo

So for example you'd have:

DateTime.TryParseExact(date1, formats,
     new global::System.Globalization.CultureInfo("en-US"), 
     global::System.Globalization.DateTimeStyles.None, out startTime);
Jon Skeet
I've suggested a workaround in an edit, but you *still* haven't really explained what you're doing.
Jon Skeet
They're not statements - my point is that everywhere in the script where you use "DateTimeStyles", use "global::System.Globalization.DateTimeStyles" and the same for CultureInfo.
Jon Skeet
And no, you still haven't provided any context. What is this XSLT script being applied to? Why can't you just write a method to do all this in the first place, and call that method?
Jon Skeet
its done thanx :)
infant programmer
+3  A: 

The bug is on this line:

DateTime.TryParseExact(date1, formats, new CultureInfo("en-US"), DateTimeStyles.None, out startTime);

Did you reference the System.Globalization namespace?

As @JonSkeet suggested, a workaround is to update your references like so:

global::System.Globalization.DateTimeStyles
global::System.Globalization.CultureInfo
Chris Ballance
@Chris Ballance, I feel sorry for misbehaving .. I am not writing it to convey you to help me in future .. but I just felt like .. that wasn't a proper attitude I could have been thankful for someone who's intended to help .. really sorry ..
infant programmer
No worries. The bulk of the folks here are quite nice and very helpful. Instead of just downvoting answers that aren't 100% correct, ask for clarification or more info and most responders are happy to adjust their answer to better address your question. I reserve downvotes for clearly wrong answers.
Chris Ballance
ohk .. thanx :)
infant programmer
+2  A: 

It is often easier to move scripts into extension-objects; you do this by exposing a regular method on a basic object, and using XsltArgumentList to expose it in an xslt namespace:

XsltArgumentList args = new XsltArgumentList();
args.AddExtensionObject("my-namespace", obj);

In your xslt, you associate your namespace-alias with the namespace, and just use "alias:someFunc(...)" in the xslt. This gives you better IDE support (but you can't just use xslt); example:

using System;
using System.Globalization;
using System.IO;
using System.Xml.XPath;
using System.Xml.Xsl;
public class MyExtensionObject
{
    private static string[] formats = new string[] { /* ... */ };
    public string dateDiff(string x, string y)
    {
        CultureInfo culture = new CultureInfo("en-US");
        TimeSpan delta = DateTime.ParseExact(y, formats, culture, DateTimeStyles.None)
            - DateTime.ParseExact(x, formats, culture, DateTimeStyles.None);
        return delta.ToString();
    }
}
class Program
{
    static void Main()
    {
        XsltArgumentList args = new XsltArgumentList();
        args.AddExtensionObject("my-namespace", new MyExtensionObject());
        XslTransform xslt = new XslTransform();
        xslt.Load("foo.xslt");
        using(TextWriter output = File.CreateText("out.txt")) {
            XPathDocument input = new XPathDocument("foo.xml");
            xslt.Transform(input, args, output);
        }

    }
}

xslt:

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:bar="my-namespace" >
    <xsl:template match="xml">
      <result value="{bar:dateDiff(date1,date2)}"/>
    </xsl:template>
</xsl:stylesheet>

xml:

<?xml version="1.0" encoding="utf-8" ?>
<xml>
  <date1>01/01/2001 00:00:00</date1>
  <date2>2/2/2002 00:00:00</date2>
</xml>
Marc Gravell
No I can't do it .. I was suppose to do it with XSLT .. but as XSLT is not a programming language .. I found this remedy of calling a C# script .. I have to call that XSL transformation from many different C# programs .. so It would be painful (rather impossible) to write this code in all calling C# code .. :( Can you find some remedy for this .. thanx for your answer ..
infant programmer
Then use the explicit approach Jon mentions that doesn't involve any using directives.
Marc Gravell
ya .. its done ..
infant programmer