Reading and/or writing xsd files

I wanted to look at reading an xsd (XML schema) file and generate C# source from it in a similar way to xsd.exe.

As XML schema is itself XML I first looked at writing the code using an XmlReader, but whilst this might be an efficient mechanism for reading the file, it’s a bit of a pain to write the code to process the elements and attributes. So what’s the alternative ?

Well there is actually a much simpler class that we can use named XmlSchema which, admittedly, will read the xsd into memory, but I’m not currently looking at performance being an issue.

Note: I’m going to deal with XmlSchema as a reader but there’s a good example of using it to write an XML schema at XmlSchema Class

Here’s a quick example of reading a stream (which contains an XML scherma)

using (XmlReader reader = new XmlTextReader(stream))
{
   XmlSchema schema = XmlSchema.Read(reader, (sender, args) =>
   {
      Console.WriteLine(args.Message);
   });
   // process the schema items etc. here
}

The Console.WriteLine(args.Message) code is within a ValidationEventHandler delegate which is called when syntax errors are detected.

Once we successfully get an XmlSchema we can interact with it’s Items, for example here some code which is intended loop through all complex types and then process the elements and attributes within each complex type

foreach (var item in schema.Items)
{
   XmlSchemaComplexType complexType = item as XmlSchemaComplexType;
   if (complexType != null)
   {
      XmlSchemaSequence sequence = complexType.Particle as XmlSchemaSequence;
      if (sequence != null)
      {
         foreach (var seqItem in sequence.Items)
         {
            XmlSchemaElement element = seqItem as XmlSchemaElement;
            if (element != null)
            {
               // process elements
            }
         }		
      }
      foreach (var attributeItem in complexType.Attributes)
      {
         XmlSchemaAttribute attribute = attributeItem as XmlSchemaAttribute;
         if (attribute != null)
         {
            // process attributes
         }
      }
   }
}