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

A better MSXSL.EXE: Adding the ability to Transform XSL with Embedded Scripts

0.00/5 (No votes)
18 Nov 2004 1  
This program creates a wrapper around the XSLT process that allows you to transform an XML file using the embedded MSXSL script.

Introduction

I am using XSL transformation in a project. So far, I have been very pleased with XSL and its capabilities. However, sometimes I find myself spending a large amount of time trying to solve a problem using XSL's set based structure. Usually, you can solve these problems, but it often takes a lot of work. In some cases, especially with dates, I have found the XSL support to be very weak (or non-existant). This is where embedded scripts come in. If I cannot find a solution to a problem using XSL, I will usually turn to an embedded script coded in C# to help solve the problem. I have written another article that contains a basic example of how to do this. Originally, I was transforming the style sheets in my custom application. However, this was tedious and I did not want to keep waiting for the entire program to load just to check if there was an error in the XSL. So, I downloaded Microsoft's MSXSL.EXE program and tried to use this to transform the XSL. I found that MSXSL would not transform the files. I kept getting the error: Invalid class file. I am not 100% sure why this is happening but my thoughts on this are that MSXSL.EXE is a wrapper around the MSXML 4.0. I do not think MSXML 4.0 supports embedded scripts. Fortunately for us - .NET does! So, I wrote my own wrapper to let me transform the XSL. Below is the relevant code for the wrapper application:

static void Main(string[] args)
{

  if( args.Length != 3 )
  {
    Console.WriteLine( "You have not entered the correct parameters" );
    return;
  }

  string xmlfile = args[0];
  string xslfile = args[1];
  string outfile = args[2];

  try
  {
    XPathDocument doc = new XPathDocument( xmlfile );
    XslTransform transform = new XslTransform();
    transform.Load( xslfile );
    XmlTextWriter writer = new XmlTextWriter( outfile, null );
    transform.Transform( doc, null, writer );
  }
  catch( Exception e )
  {
    Console.WriteLine( e.StackTrace ); 
  }
}

It is fairly basic stuff - but very useful. Below is an example XML file, the XSL file, and the output file that I used as a test.

atest.xml

<?xml version="1.0" encoding="UTF-8"?>
<root>
   <dataitem>From the xml file: item 1</dataitem>
   <dataitem>From the xml file: item 2</dataitem>
   <dataitem>From the xml file: item 3</dataitem>
   <dataitem>From the xml file: item 4</dataitem>
</root>

atest.xsl

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform">http://www.w3.org/1999/XSL/Transform" version="1.0"
     xmlns:msxsl="urn:schemas-microsoft-com:xslt"
     xmlns:utils="urn:script-items">
<msxsl:script language="C#" implements-prefix="utils">
     <![CDATA[
     public string getDate(){
          return (DateTime.Today.ToLongDateString() + " at " + 
                  DateTime.Now.ToLongTimeString() );
     }
     ]]>
</msxsl:script>
<xsl:output method="html" encoding="utf-8" />
<xsl:template match="dataitem">
 <xsl:value-of select="." /> displayed on <xsl:value-of select="utils:getDate()" />
<xsl:text>
</xsl:text>
</xsl:template>
</xsl:stylesheet>

You can transform this with:

myxsl atest.xml atest.xsl atest.htm

and you will get the result:

atest.htm

From the xml file: item 1 displayed on Thursday, November 18, 2004 at 2:38:26 PM
From the xml file: item 2 displayed on Thursday, November 18, 2004 at 2:38:26 PM
From the xml file: item 3 displayed on Thursday, November 18, 2004 at 2:38:26 PM
From the xml file: item 4 displayed on Thursday, November 18, 2004 at 2:38:26 PM

I have also included everything needed in the source and demo projects. 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