1

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

7
  • 2
    apparently the Visual studio debugger supports debugging XSLT (with breakpoints, ...) Commented Dec 11, 2009 at 15:40
  • 2
    so you want us to debug your code for you? Commented Dec 11, 2009 at 15:40
  • I think I'm going to change the menu in my IDE to add please in front of every command - make my PC a much happier place... Commented Dec 11, 2009 at 15:42
  • 4
    Actually the question is why won't it compile... Commented Dec 11, 2009 at 15:43
  • 1
    Re your comment - actually, xslt can be regarded as a programming language (a functional programming language). It might not be as simple to write some things, but it is still a programming language. Commented Dec 11, 2009 at 17:35

3 Answers 3

6

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);
Sign up to request clarification or add additional context in comments.

3 Comments

I've suggested a workaround in an edit, but you still haven't really explained what you're doing.
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.
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?
3

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>

2 Comments

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 ..
Then use the explicit approach Jon mentions that doesn't involve any using directives.
3

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

2 Comments

@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 ..
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.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.