Click here to Skip to main content
Click here to Skip to main content
Go to top

XSL Transform Code Generator for Visual Studio .NET

, 8 Feb 2006
Rate this:
Please Sign up or sign in to vote.
A custom tool for Visual Studio .NET which runs an XSL transformation to generate code.

Sample Image - TransformCodeGenerator.gif

Introduction

After reading an article on CodeProject entitled VS.NET CodeDOM-Based Custom Tool for String Resource Management by Jasmin Muharemovic, and finding the StringResourceTool custom tool for string resources, I discovered how easy it is to create a custom tool for Visual Studio .NET.

The Problem

In order to generate code, you use the CodeDOM objects, which appear to be fairly complex and cumbersome to code. Also, if the "source" file for the code generation is in some text format, then a whole lot of string parsing needs to be performed to extract the "parameters" required to generate the appropriate code.

Another issue is that, each time you want to generate something else, you have to create another custom tool and register it in Visual Studio. This could lead to a "DLL hell" of custom tools, as well as trying to remember each one's name would be difficult.

The Solution: XML + XSLT

XML takes all this hard string parsing stuff away, and provides a powerful mechanism (XPath) for extracting whatever you want out of the XML file. XSLT provides a flexible mechanism for producing output in any format. Thus, I adapted the custom tool code to run an XSL transform instead of producing the generated code.

In this way, each time I want to create a new type of code generator, I just invent a new XML schema for the source file and a corresponding XSL transform to generate the required code.

How it Works

There are two requirements for the TransformCodeGenerator to work properly:

  • The XML source files root element must contain an attribute called "transformer". The value of this attribute specifies which XSLT file to use for the transformation.
  • The XSLT filename may be fully qualified, or just the file name, in which case, the file must reside in the same directory as the XML file (in the project), or in the same directory as the TransformCodeGenerate.dll files.

Add your XML file to your Visual Studio solution, and set the CustomTool property to TransformCodeGenerator. Each time you modify and save the XML file, the custom tool will regenerate your code.

Sample Project

I created two sample XML files to illustrate the possible usage for this custom tool.

I invented an XML schema which describes a WinForms form with some controls on it. Check out the "MyXMLForm.xml" file in the test project. The accompanying XSLT transform, "MakeXMLFormCode.xslt", transforms this into code which creates a class which has fields for each control, creates a new instance of each control, sets the control properties, and adds them to the form.

The second example is for "type-safe" DataTables. This XML file describes a database table in a more friendly way than an XSD file. This time, the XSLT generates two classes which inherit from DataTable and DataRow, respectively. The DataRow class will have type-safe properties for each column that the DataTable contains. You could take this sample further by creating a tool which reads a database schema and produces this XML file... Smile | :)

Conclusion

XML + XSLT provides a powerful way to produce code generated code, and now with the TransformCodeGenerator custom tool for Visual Studio, it's a whole lot easier than running an external tool to run the transform.

Credits

Please note: This article does not intend to go into the details of how to author XML files or XSLT transformations.

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

Share

About the Author

Chris Stefano
Software Developer (Senior)
South Africa South Africa
I'm a developer specializing in software for the financial services industry particularly in the decision support area. Currently my specialty is in investment compliance.

Comments and Discussions

 
QuestionVS2008, VS2010, VS2012, etc. PinmemberQwertie27-Oct-13 11:29 
GeneralXSLT 2.0 PinmemberDmitri Nesteruk1-Nov-07 20:10 
GeneralRe: XSLT 2.0 PinmemberChris Stefano1-Nov-07 20:18 
GeneralRe: XSLT 2.0 PinmemberDmitri Nesteruk3-Nov-07 22:34 
GeneralRe: XSLT 2.0 PinmemberChris Stefano4-Nov-07 7:10 
GeneralSaxon.NET PinmemberDmitri Nesteruk4-Nov-07 22:46 
Easily? I don't think so. I spent half a day trying to get it to work, and failed. Not really surprised, considering it's Java-based and uses a .NET Java VM. In the end, I went with Altova XML engine, which is free and works beautifully. Here's the code:
 
public override string DoGenerateCode(string inputFileName, string inputFileContent)
    {
      string transformerFileName = "NOT FOUND";
      string result;
      try
      {
        FileInfo inputFileInfo = new FileInfo(inputFileName);
        // get the source document
        XmlDocument sourceDocument = new XmlDocument();
        sourceDocument.LoadXml(inputFileContent);
        // get the filename of the transformer
        string transformerFile = sourceDocument.DocumentElement.Attributes["transformer"].Value;
        if (!File.Exists(transformerFileName))
        {
          // try in the same dir as the file
          transformerFileName = Path.Combine(inputFileInfo.DirectoryName, transformerFile);
 
          if (!File.Exists(transformerFileName))
          {
            // try in the dir where this dll lives
            FileInfo assemblyFileInfo = new FileInfo(Assembly.GetExecutingAssembly().Location);
            transformerFileName = Path.Combine(assemblyFileInfo.DirectoryName, transformerFile);
          }
        }
        FileInfo fi = new FileInfo(inputFileName);
        AssemblyName assemblyName = Assembly.GetExecutingAssembly().GetName();
        // Transform
        ApplicationClass c = new ApplicationClass();
        IXSLT2 x = c.XSLT2;
        x.InputXMLFileName = inputFileName;
        x.XSLFileName = transformerFileName;
        result = x.ExecuteAndGetResultAsString();
      }
      catch (Exception ex)
      {
        StringBuilder sb = new StringBuilder();
        sb.AppendLine("/*");
        sb.AppendLine("\tERROR: Unable to generate output for template:");
        sb.AppendFormat("\t'{0}'{1}", inputFileName, Environment.NewLine);
        sb.AppendLine("\tUsing transformer:");
        sb.AppendFormat("\t'{0}'{1}", transformerFileName, Environment.NewLine);
        sb.AppendLine("");
        sb.AppendLine(ex.ToString());
        sb.AppendLine("*/");
        result = sb.ToString();
      }
      return result;
    }

GeneralRe: Saxon.NET PinmemberChris Stefano5-Nov-07 4:06 
GeneralRe: Saxon.NET PinmemberDmitri Nesteruk17-Nov-07 23:21 
GeneralRe: Saxon.NET PinmemberChris Stefano18-Nov-07 6:33 
QuestionHow to create multiple output file for a sigle input file? PinmemberJonas A21-Sep-07 1:23 
AnswerRe: How to create multiple output file for a single input file? PinmemberChris Stefano21-Sep-07 1:35 
GeneralRe: How to create multiple output file for a single input file? PinmemberJonas A21-Sep-07 1:50 
GeneralRe: How to create multiple output file for a single input file? PinmemberChris Stefano21-Sep-07 1:55 
GeneralRe: How to create multiple output file for a single input file? PinmemberDmitri Nesteruk4-Nov-07 22:48 
GeneralRe: How to create multiple output file for a single input file? PinmemberChris Stefano5-Nov-07 3:58 
GeneralRe: How to create multiple output file for a single input file? PinmemberDmitri Nesteruk5-Nov-07 6:44 
GeneralWinform to class Pinmembercmschick30-Jan-07 1:58 
GeneralRe: Winform to class PinmemberChris Stefano30-Jan-07 4:10 
GeneralNice! Pinmemberrstaylor14-Feb-06 18:20 
GeneralXML, XSLT and Dynamic Business Rules PinmemberSluggish13-Feb-06 7:41 
GeneralRe: XML, XSLT and Dynamic Business Rules PinmemberChris Stefano13-Feb-06 9:45 
GeneralCode Generation PinmemberByteGhost12-Feb-06 23:38 
GeneralRe: Code Generation PinmemberChris Stefano13-Feb-06 3:27 
QuestionVS2003 Support PinmemberChris Stefano10-Feb-06 4:16 
GeneralUsing xml and codedom PinprotectorMarc Clifton8-Feb-06 17:16 
GeneralRe: Using xml and codedom PinmemberChris Stefano8-Feb-06 20:46 
GeneralRe: Using xml and codedom PinmemberLimeyRedneck14-Feb-06 8:33 
GeneralRe: Using xml and codedom Pinmemberleppie10-Feb-06 4:49 
GeneralRe: Using xml and codedom PinmemberLimeyRedneck14-Feb-06 8:14 
GeneralRe: Using xml and codedom PinmemberChris Stefano14-Feb-06 8:42 
GeneralRe: Using xml and codedom Pinmemberleppie14-Feb-06 9:27 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

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

| Advertise | Privacy | Mobile
Web02 | 2.8.140916.1 | Last Updated 8 Feb 2006
Article Copyright 2006 by Chris Stefano
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid