Click here to Skip to main content
6,931,354 members and growing! (20,017 online)
Email Password   helpLost your password?
Languages » XML » XML/XSLT     Intermediate

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

By ritzcoder

This program creates a wrapper around the XSLT process that allows you to transform an XML file using the embedded MSXSL script.
C#, XML, Windows, .NET1.1VS.NET2003, Dev
Posted:18 Nov 2004
Views:28,365
Bookmarked:13 times
printPrint Friendly   add Share
      Discuss Discuss   Broken Article?Report  
3 votes for this article.
Popularity: 2.07 Rating: 4.33 out of 5

1

2
1 vote, 33.3%
3

4
2 votes, 66.7%
5

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

About the Author

ritzcoder


Member

Location: United States United States

Other popular XML articles:

Article Top
You must Sign In to use this message board.
FAQ FAQ 
 
Noise Tolerance  Layout  Per page   
 Msgs 1 to 3 of 3 (Total in Forum: 3) (Refresh)FirstPrevNext
GeneralXsltArgumentList Pinmembercbowl15:53 29 Nov '04  
GeneralA warning... PinmemberBrian Nottingham13:42 19 Nov '04  
When using the msxsl:script blocks in XSL files, each time you load an XslTransform an assembly is compiled and created on the fly with the code in the script block.

This assembly is loaded into the current AppDomain, and since assemblys cannot be individually unloaded from an AppDomain, it stays loaded until program termination. So if you use these msxsl:script blocks in an application that runs for long periods at a time and does many transformations, you will eventually get an OutOfMemoryException.

Instead of putting the code in the msxsl:script blocks, if its possible I would recommend implementing the functionality in a class in your application, and then pass in an instance of that class as an extension object using the XsltArgumentList.

Brian
GeneralNXSLT PinmemberColin Savage19:35 18 Nov '04  

General General    News News    Question Question    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+PgUp/PgDown to switch pages.

PermaLink | Privacy | Terms of Use
Last Updated: 18 Nov 2004
Editor: Smitha Vijayan
Copyright 2004 by ritzcoder
Everything else Copyright © CodeProject, 1999-2010
Web17 | Advertise on the Code Project