6

I am looking to create a simple code generator to convert XSD definitions to C# classes. This is partly as a learning exercise, but I would also like to get some practical use out of it eventually.

What would the general design of such an application look like? I assume that I will need to use one of the XML parsers in the .NET framework, but which one? And what will the resulting data structure look like? Will it be an expression tree?

From there, what happens? Do I generate code by concatenating strings, or are there better, more sophisticated ways to do it?

Important: I'm not looking for someone to write code for me (although very brief code samples are welcome, if they are applicable), and I don't need someone to do the research for me. I'm perfectly capable of reading about parsers, expression trees and code generators myself. I just need someone to help me with the broad brush strokes, so that I don't walk into too many blind alleys.

I'm also aware of open source projects like XSD2Code, but I'd rather make the attempt myself first, for learning reasons, and because the resulting tool is likely to be highly specific to my particular scenario.

2
  • “Do I generate code by concatenating strings” You can try using CodeDOM. If that doesn't work out (there are some things CodeDOM doesn't support well), try using Roslyn.
    – svick
    Aug 2, 2013 at 12:40
  • You may well find this interesting even if you don't choose to make use of it - given your question Im sure you'll like it. msdn.microsoft.com/en-US/roslyn
    – bUKaneer
    Aug 5, 2013 at 16:18

4 Answers 4

3

What would the general design of such an application look like?

Leaving aside trivalities like UI, you'll want to have at least three major parts:

  1. The "core" app, that translates the XML object into a C# string.
  2. The portion that locates and reads the XSD file as XML, and passes each object over to the core app to process.
  3. The portion that writes out the C# strings.

You'll want #1 to have a fair bit of available recursion, since XSD elements can be of types that contain elements and types and elements.

I assume that I will need to use one of the XML parsers in the .NET framework, but which one?

I'd load the whole XSD as a single System.XML.XMLDocument class, but I'm from the web and learned XML via the DOM. It's also the older model, and starting with things like selectSingleNode is probably better to start out with than performance-optimizing interfaces like XmlReader, or non-microsoft XML parsers.

And what will the resulting data structure look like? Will it be an expression tree?

Why wouldn't it be a namespace of structs or classes?

From there, what happens? Do I generate code by concatenating strings, or are there better, more sophisticated ways to do it?

There are no better ways to output strings from a program than concatenating strings. There is just syntactic sugar to make the code easier to write. But you want to use a System.Text.StringBuilder here, instead of mucking about with code like follows:

string Line = new String();
Line = "public class " + xmlDoc.localName + "() {\n";
Line += "etc, etc.";
1
  • Why wouldn't it be a namespace of structs or classes? -- I guess I just assumed that I wouldn't be performing the transcoding directly, that there would be some form of intermediate data representation. But your overall description makes it seem like this might be easier than I thought, or at least shallower than I thought. Aug 2, 2013 at 5:47
1

Abstract Algorithm


Transform(input)

When Transform is called with the argument input.

  1. If input is not valid XML then report error
  2. Let xml be the result of transforming input into an abstract representation of XML
  3. If xml does not conform to XSD then report error
  4. Let CSharp be the result of transforming xml into an abstract representation of CSharp code
  5. Let output be the result of transforming CSharp into a String
  6. Return output

C# Stub


public static string Transform(string input)
{
    var xml = ConvertStringToXml(input);    
    ValidateXsdSchemaConformance(xml);
    var csharp = ConvertXmlToCSharp(xml);
    return ConvertCSharpToString(csharp);
}
1
  • 1
    Extremely high-level pseudocode. Nice. :) Aug 2, 2013 at 6:13
1

People use ASTs basically because a general parsing algorithm (such as a parser generator might employ) can't do any better, not because an AST is a fantastically convenient semantic model.

In your case, other people have conveniently written both a parser and some basic degree of a semantic model as part of the XML parser implementation. So you definitely want to start there.

To me it seems like the biggest decision is whether to generate the code directly from the XML DOM, or whether to create your own semantic model and populate that from the DOM, then generate C# code from there. The intermediate step is more work and more complexity, but probably scales better if you plan to eventually add a lot of options about exactly what gets code generated. I suppose in theory the intermediate step would make it somewhat easier to support a format other than XSD, but that seems a far-fetched use case.

As far as what to use to generate the code, I've tried using the System.CodeDom classes to build up code programatically in a syntax-independent way - and I hated it. For most situations it's far easier to build up a code string and just tell it to compile the string. I can imagine a situation where your Code Generation code needed to make changes that caused ripple effects throughout the string you were generating to the point where building a string was the more difficult path, but I've never encountered it - and I like using code generation.

1
  • Sorry Robert, I just saw your question and you've probably done it by now, which cuts the chance of this being helpful down a bit.
    – psr
    Sep 20, 2013 at 17:34
0

AIUI, expression trees are for internal manipulation of a single lambda function, not for representing an entire class. For the intermediate representation to output half of the design your main options are a custom AST and string concatenation (as suggested in another answer) or CodeDOM. The latter is quite verbose but would give you flexibility if you decide that you want to emit VB, JS, or whatever else Microsoft chooses to add in the future.

At heart it's the old tradeoff between KISS and enterprisy.

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.