Strangeness. Carrying on at a leisurely pace with my XSD-entender TDD project, I come across a couple of issues. The first is yet another inconsistency inside the XmlSerializer although not a bug. It’s a case of obsolescence. In .NET 1.0, you compile an XmlSchema object like this.

XmlSchema xsd = new XmlSchema();
xsd.Compile();

Now in .NET 2.0, Microsoft marked the XmlSchema.Compile() method as Obsolete in favour of using the XmlSchemaSet.Compile() method like so

XmlSchema xsd = new XmlSchema();
XmlSchemaSet set = new XmlSchemaSet();
set.Add(xsd);
set.Compile();

We can add more schemas into the schemaset and then compile them into one large schema which we can access through such properties as GlobalItems and GlobalTypes. We can also continue to access the individual schemas through the Schemas property. Good so far, but here’s the problem.

As part of emulating how xsd.exe works, we use an XmlSchemaImporter object like so

//Create importer for the schema
XmlSchemaImporter importer = new XmlSchemaImporter(schemas);

// Iterate through top-level (global, not local) elements in the schemas
// and export code for each into the namespace
foreach (XmlSchema schema in schemas)
{
foreach (XmlSchemaElement element in schema.Elements.Values)
{
// Import the mapping from XML to .NET code and export it to the code namespace
XmlTypeMapping mapping = importer.ImportTypeMapping(element.QualifiedName);
exporter.ExportTypeMapping(mapping);
}
}
return ns;

The XmlSchemaImporter object only takes an XmlSchemas object in its constructor. So, having compiled a schema in a SchemaSet, I then need to take it out of there and put it in the XmlSchemas collection instead with something kludgey(?) like this

public XmlSchemas MoveSchemaSetToXmlSchemas(XmlSchemaSet set)
{
  XmlSchemas schemas = new XmlSchemas();
  XmlSchema[] schemaArray = new XmlSchema[set.Count];

set.CopyTo(schemaArray, 0);
foreach (XmlSchema xsd in schemaArray)
{
schemas.Add(xsd);
}
return schemas;
}

Now the XmlSchemas object also has a Compile() method but calling it seems to do nothing. The IsCompiled property of the object will remain false even if the object contains a valid schema. Even MSDN says it is for calling internally only. Fair enough. So how do you compile several schemas into one and then pass them into a XmlSchemaImporter object?

  • The obvious way would be to create a new XmlSchemaImporter constructor which takes a XmlSchemaSet object. Well yes, but MS has already been asked that and they’ve said no. Not even for .NET 3.5 by the looks of it.
  • Well then, how about being able to export the compiled schema from a schemaset into a single XmlSchema and thence into a XmlSchemas? No word yet but something like XmlSchema xsd = schemaset.ExportCompiledSchema() would be nice.

In the end, the app works with the kludge but is it really necessary? Let’s see if option two ever shows up.