There's no reason you couldn't use the same approach xsd.exe
uses, but then run your own code against the generated CodeDOM model to make the modifications you need before writing out the .cs files to disk.
The general idea is that you load your XSD file into an XmlSchema
object, then use the internal XmlCodeExporter
and XmlSchemaImporter
classes to populate a CodeDOM namespace.
After you've done that, you're free to make any tweaks you need to make against the CodeDOM AST, and then write it out to disk.
Eg.
XmlSchema schema = null; // Load XSD file here
var schemas = new XmlSchemas();
schemas.Add(schema);
var ns = new CodeNamespace { Name = "MyNamespace" };
ns.Imports.Add(new CodeNamespaceImport("System"));
ns.Imports.Add(new CodeNamespaceImport("System.Collections.Generic"));
var exporter = new XmlCodeExporter(ns);
var importer = new XmlSchemaImporter(schemas);
foreach (XmlSchemaElement element in schema.Elements.Values)
{
var mapping = importer.ImportTypeMapping(element.QualifiedName);
exporter.ExportTypeMapping(mapping);
}
// Transform CodeDOM as required, adding new attributes, methods, modifying
// inheritance hierarchy, whatever.
var provider = new CSharpCodeProvider();
using (var writer = new StreamWriter(outputFile, false))
provider.GenerateCodeFromNamespace(ns, writer, new CodeGeneratorOptions())
If your schemas reference other schemas, you'll have to use XmlSchemaSet
, and set the XmlResolver
property to a resolver that you write, which will find the imported schemas and provide them to the XmlSchemaSet
when you call Compile()
on it.
It is possible for imported schemas to declare things in a different namespace, and if you want your XmlSerializer
to generate XML with the imported items in a different namespace, you may have to hack the generated CodeDOM a fair bit.
But it is possible.
Good luck!