Delta Engine Blog

All about multiplatform and game development

Generating Xml data from Xml Schemas

Today I was playing around with Xsd (Xml Schema) files a bit for automatic Xml generation of specific types I need for an editor. Starting to work with Xsd files isn't that hard, looks like Xml, but stuff is named "element", "complexType", "sequence", etc. Once you are familar with that you can easily write Xsd files (but please, not another "Customer" example, I'm going to puke), which validate your Xml data automatically for you. But I don't wanted to do that, I just need a clean and easy way to generate specific types like Colors, Vectors, Material parameters, etc. Btw: Everthying shown here is only intended to be used by the Editor, Artists don't want to work with Xml files and I don't think Programmers should either. Let the work be done by the computer.

The things I will cover here don't use much of the keywords in Xsd. See References and your MSDN help for a complete overview what you can do with Xsd (or any other Xml Schema for Validation). For a more complex and longer example of an useful Xsd file see the Google sitemap xsd file. I on the other side try to keep things simple. Instead of using 6 xml lines for describing just a color, I prefer 1 simple line (using xml attributes instead of child nodes).

Here is the sourcecode for this article (requires .NET 2.0 and uses NUnit). Take a look at the unit tests to see how to use this code.

Ok, here is an examples using Xsd (you might notice I don't use namespaces or annotations, they only bloat things up ^^ If your Xsd files get more complex, you should think about expanding them.):

And this would generate by default:

Or a more useful example inside the Material node:

So, how do we do all that stuff? Yes, exactly, by using the System.Xml.Schema namespace. All the required classes are in there, but most function do only check your code or help you to analyse. We want to create xml. Anyway, we have always start with loading and compiling the Xsd file first. If anything goes wrong here, you will get an exception explaining what you did wrong in the Xsd file. This is the handy dandy method I use for loading XmlSchemas:

If you want to load a bunch of Xsd files (I already have created around 30 of them in just a couple of hours ^^), it is much better to add them all to the same XmlSchemaSet and compile them all at once. Note: This has the disadvantage that any compiling error will result in all the rest of the schemas not to be loaded. But it is much faster this way.

We need 2 more methods for our goal to generate a xml node. This first one will create the xml node and go through all schema items (only ComplexType items are handled in this example) if possible. Then it returns the child node to allow maybe changing some more things.

And finally we use this method to fill in all the xml elements and using the default values (you can specify them with default="value" in the xsd file). First we go through all child nodes and recursively call this function again until all nodes are handled. Then we go through all schema attributes and add them as well.

Ok, there is one helper method missing for getting the default value. Lets assume that most elements don't have a default element and will return an empty string for the default value. It is much more useful to have "real" default values like 0 or false and thats excatly what TryToFindDefaultValue is for:

Ok, that it. Now you can create nodes from any loaded schema using code like this one from the unit tests (see project files above):

Btw: You can also use Visual Studio to edit or create xsd files in a more fancy way, but I didn't found it more productive than typing in xsd directly for small xsd files.

References:

Have fun.