I've been asked a couple times now so I've decided to write up an article based on this. Here at the office I figured out how to take an XSD and make it happy c# class ...even if you get a crappy XSD file.
XSD.exe is a tool that comes with the microsoft SDK. This is a magical little tool that can create objects from XSDs. As I posted about before, this does not guardentee it will be switched out to a nice class for you to do stuff with. (By the way, thanks Mr. Keller, everytime I hear/think/say that I now repeat it 3 times.) So there you are with the junk XSD from deep within the Cidadel with no uber cool gravity gun to smack this thing into submission and those annoying strom trooper guys are headed your way (or your PM, either or) and it's just got to work, so you bust out the crowbar SDK command line and type the following...
xsd.exe crappySchema.xsd /c /n:MyNamespace
and it tells you too bad, no can do because of some useless error that will leave you confused and fusterated. So now what? Hack your code somewhere and throw this in.
DataSet set = new DataSet();
set.ReadXmlSchema("crappySchema.xsd");
set.WriteXmlSchema("niceSchema.xsd");
This will give you two things. 1, verification your xsd is not total utter crap (otherwise it will bomb out on ReadXmlSchema) and 2, a nicely generated xsd. If you get no response/error from the app, you have a new file on your drive named niceSchema.xsd. Now you can continue on creating your class to work with this. Try the xsd.exe again...
xsd.exe niceSchema.xsd /c /n:MyNamespace
Depending on how large the schema is, here is what your output should result in...
C:\>xsd.exe niceSchema.xsd /c /n:MyNamespace
Microsoft (R) Xml Schemas/DataTypes support utility
[Microsoft (R) .NET Framework, Version 2.0.50727.312]
Copyright (C) Microsoft Corporation. All rights reserved.
Writing file 'C:\niceSchema.cs'.
Great! This is what we want. Now, I personally hate arrays -- so I go into the newly generated class and look for any/all "[]" and replace them with a list. So within our schmea, we find this...
private SchemaItem[][] schemaItem;
An array of arrays?! Yep, your eyes do not lie to you (at least right now). I remove all double arrays as well -- it appears to have NO effect on the output which we will get to later, so switch those out to List<SchemaItem> schemaItem; and move on, replacing all of them. Oh, and you probably want to add in using System.Collections.Generic; just for fun.
Ok, now we have a class ready for action. To cover the first part, I'm bringing data into my world from an expected XML doc that fits my schema ...at least close enough anyway.
XmlReader reader = XmlReader.Create(filename);
SchemaItem item = new SchemaItem();
XmlSerializer serial = new XmlSerializer(typeof(Schema.SchemaItem));
try
{
item = (SchemaItem)serial.Deserialize(reader);
}
catch (Exception ex)
{
Console.WriteLine("unable to read xml file as " + Schema.GetType().ToString());
throw ex;
}
If everything is going according to plan, you'll have a bunch of data into your class. Now you've done a bunch of really cool stuff to your SchemaItem ..its time to write that puppy out.
private StringWriter SerializeToClass <T>(object value)
{
StringWriter writer = new StringWriter(new StringBuilder(), Encoding.UTF8);
System.Xml.Serialization.XmlSerializer serialized = new System.Xml.Serialization.XmlSerializer(typeof(T));
serialized.Serialize(writer, value);
writer.Close();
return writer;
}