Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Embedding a Date Formatting Script in an XSL File

0.00/5 (No votes)
12 Nov 2004 1  
This example shows you how to use Microsoft's XSL script extensions to add custom scripts to your XSL file.

Introduction

If you use XSL a lot, you will sometimes run into limitations imposed by the set based nature of XSL. If you are using XSL with Microsoft's .NET platform, there are a few things you can do to get past these problems. I ran into a problem with XSL when I wanted to do some date formatting. I found that for date parsing, the base XSL functions are terrible. If you want to use more powerful functions you could check out EXSLT. However, I tried that approach and although there are a number of articles about how to get EXSLT work in .NET, they mostly revolve around an extension that has been written in gotdotnet.

I have an inherent trust of gotdotnet projects because - and I know this sounds like a silly reason - the gotdotnet workspace software is terrible. GotDotNet seems to be down most of the time (for example when I went to download the EXSLT files today it was down) and I can never find anything - the search is terrible, it seems totally disorganized. They really need to take a lesson from SourceForge or CodeProject. Also, I have to laugh at the custom error I always see telling me that the administrators are aware of the problem over at gotdotnet. Poor people - they must be very busy.

Anyway, if you are willing to use this custom extension EXSLT.NET and you can actually download it, I am sure it is just great. However, it requires linking your project to a DLL and although you get the source code, I am just not sure I need such a heavy solution for my problem. Oh - my problem? I just want to turn a date returned from a node in an XSL style sheet from a datetime to a full text format. This should not be so complicated, right? Well, I did not want to use EXSLT.NET just for that. So, I am going to offer you another alternative. You can embed script in your XSLT page. While this may not be the best solution in all cases, it works well when you will not be able to easily change and recompile the back end engine you have written to transform the style sheet but you will have easy access to the XSL files. So, to do this, you first declare your namespace:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform "version="1.0"
    xmlns:msxsl="urn:schemas-microsoft-com:xslt" 
    xmlns:myutils="http://mycoolplace.com">
  • The first line you should be really familiar with by now :-)
  • The second line just tells the compiler you want to use the wonderful Microsoft extensions.
  • The third line tells the parser that you are not crazy and you will really be including some function (s) from the myutils namespace - please don't worry about that odd function when you run into it - just continue along your parsing way until you find it later in the code.

Next you create your XSL style sheet as normal. When you get to the part in your style sheet where you want to call a custom function, say inside a template match, just do this:

<xsl:template match="TheItemThatNeedsAPrettyDate">
     <xsl:value-of select="utils:ConvertDate(DateItem)"/>
</xsl:template>

DateItem contains the date that we want to convert. In this case, it should be directly below the match node. In theory you should be able to give any XPath expression - however, I ran into annoying troubles with that so I do not know if my XPath expression was wrong or if there is some other kind of problem. I finally just gave up since the basic expression (which was all I needed for my project) worked.

Now we need to create the function: just do this at the bottom of your file (above the closing style sheet tag):

<msxsl:script language="C#" implements-prefix="myutils"> 
 public string ConvertDate( XPathNodeIterator nodeit ) 
 {
    if(nodeit.MoveNext()) 
    {
       XmlNode node = ((IHasXmlNode)nodeit.Current).GetNode();   
       try 
       {
           DateTime dt = DateTime.Parse( node.InnerText );
           return dt.ToString( "f" );
       }   
       catch 
       {    
           return "Convert Error";
       }
    }
    return "No date found";
 }
</msxsl:script>

There is a lot of fun stuff with XPathNodeIterator here - I don't know who thought up of that weird convoluted syntax at Microsoft but rest assured - there was a better way!!! It almost seems that Microsoft used this XPathNodeIterator and the whole XPathNavigator mess just to make our lives harder. Hopefully in the next version of .NET this will be a little less complicated. I read all about it at .NET and XML by Orielly and I suggest you pick up that book if you want the gory details of what is going on here. That is all there is to it. The only complicated part of this is turning that XPathNodeIterator into something that is actually useful. Well that is it. I will revisit this article shortly and post a more detailed explanation of how the XPathNodeIterator is working if anyone expresses any interest. I will also upload some sample files if anyone is interested. I hope this helps someone.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here