darren david, gui geek

The .NET XML Schema Definition Tool -or- How I Learned to Stop Parsing and Love the DOM (Part 1)

Coming to WPF from the ActionScript world, I’m constantly amazed at what a mature framework like .NET brings to the table. I’m so used to rolling everything from scratch that it usually takes me a few hours of starting down a path, then googling for help and realizing that I can end up doing what I needed to do in only a few lines of code. I remember the first time that I learned about automagic XML object deserialization and I was just floored - who needs XPath when the framework turns XML into typed objects on the fly? (And why didn’t they tell me that 2 years ago before I spent 3 days writing a custom deserialization layer?)

Well, that’s all well and good, but Microsoft has taken this one step further with the XML Schema Definition Tool that ships with the .NET 3.0 SDK. The workflow here is simple and powerful. All you have to do is create a schema, run the XSD utility, and all of your model classes are generated in the .NET language of your choosing, with options to include WPF databinding support (INotifyPropertyChanged, INotifyCollectionChanged) and even to create a .NET DataSet. Let’s take a look at how this works.

For this example I’m going to generate a schema for a self-running slideshow application. Let’s have a look:

Playlist schema image
This application will be able to play one or more Playlists. Each Playlist controls the playback order of one or more Slides, each of which contains a reference to a single Layout that controls 1-5 Assets. This diagram is great for getting a high-level view of the data model, but it doesn’t show the attributes that are assigned to each element. For that, you’ll have to download the .xsd (2Kb). Note that all elements that I want to become unique classes have been flagged as global elements within the XSD.

Now that we’ve figured out how our data model is going to work, we can go about generating classes based on the model. Open up the SDK Command shell (it sets env vars that include all of the useful tools in the PATH) and navigate to the directory that contains your schema. We’ll run the xsd.exe file from here, but first, let’s have a quick look at the application parameters that matter to us:

/c[lasses]
Generates classes that correspond to the specified schema.

/d[ataset]
Generates a class derived from DataSet that corresponds to the
specified schema.

/l[anguage]:language
Specifies the programming language to use. Choose from CS
(C#; default), VB (Visual Basic), JS (JScript),
or VJS (Visual J#).

/n[amespace]:namespace
The namespace for generated class files. The default namespace
is the global namespace.

/enableDataBinding | /edb
Implement INotifyPropertyChanged interface on all generated types
to enable data binding.

/out:directoryname
The output directory to create files in.

There are many more options than these, simply run xsd.exe from the shell prompt to see complete usage instructions.

I like me a well-organized project file, so I’m going to use a namespace of Player.Model. I’m also going to enable databinding so that I can bind my datasource to whatever controls might be in my app. Here’s what this looks like in action:

Voila! Here is the generated class.

So now what? First, I’ll generate some sample XML based on my schema. Once that’s ready to roll and placed where my project can find it, it’s only 4 lines of code to load in the XML and generate bindable, strongly-typed objects:

XmlSerializer serializer = new XmlSerializer( typeof( Playlists ) );
StreamReader reader = new StreamReader( @"ContentPlaylists.xml" );
Playlists playlists = serializer.Deserialize( reader ) as Playlists;
reader.Close();

Now, the playlists variable contains a property called Playlist, which is a strongly-typed collection of all of our Playlists. From there, I can bind to that collection, or drill down inside to get to whatever data I need. How easy was that? I could also have generated a .NET DataSet, which would allow me to query against the data as if I were connected to a database. Sweet.

Here’s a small WPF Project (10Kb) that shows all of this fanciness at work, including a very simple databinding example. While this is a huge time-saver, the one catch is that the C# file is auto-generated, meaning that you don’t want to go mucking around in there to extend your model classes — if you change your schema and regenerate your classes, all of your edits get blown away. Stay tuned for Part 2, in which I’ll explain how to use partial classes in .NET to get around this limitation.

Thanks to Robby for urging me to post about this. It raises an interesting point - the more that visual designer/developers (like us Flash geezers, and even former WPF PM’s like Robby) work with WPF/Silverlight, the more rediscovery of pre-WPF .NET functionality is going to occur. I’m sure .NET diehards chuckle as I swoon over tools that they’ve relied on for ages, but there’s a new game in town, with a new wave of developers coming on board. The .NET framework is MASSIVE and it’s useful for us non-MSCE certified geeks to make the connection between learned behaviors and newfound tools.

(OK, I know the title should probably be How I Learned to Stop Parsing and Love the Schema, but come on, it sounds so much better with DOM in there. :) )

| Trackback

9 Comments so far

  1. Mike Brown June 5th, 2007 1:47 pm

    Nice blog you have here. Congrats on the jumbo tron multitouch interface. I just wanted to let you know that the XSD tool has been around for a while…I believe since .Net 1.1

    It definitely simplifies getting XML in and out of your application.

  2. Darren June 5th, 2007 9:05 pm

    Agreed, but I /believe/ that the ability to enable data binding (i.e. implementing INotifyPropertyChanged) was added recently. Please correct me if I’m wrong…

  3. [...] powerful feature in .NET is a tool in the sdk called xsd.exe.  Darren David actually has a fabulous post on exactly the power of this tool: never touch a DOM or XPATH again!   His post [...]

  4. Eriawan Kusumawardhono June 26th, 2007 3:49 am

    Hi Darren,

    CMIIW, but this tool, xsd.exe, it’s been in .NET since .NET 2.0 SDK. Of course, it’s also available in the sequent versions of .NET, including .NET 3.0, 3.5 and beyond.

  5. Sebastien Lambla June 27th, 2007 1:33 am

    Hey Darren,

    Xsd has been generating INotifyPropertyChanged since .net 2. See http://serialseb.blogspot.com/2007/06/xsdexe-passed-away-svcutilexe-is-way-to.html

  6. [...] powerful feature in .NET is a tool in the sdk called xsd.exe.  Darren David actually has a fabulous post on exactly the power of this tool: never touch a DOM or XPATH again!   His post [...]

  7. Mike July 25th, 2007 11:19 am

    So what is the difference between .net 2.0 & 3.0 xsd versions?
    2.0 includes “Runtime Version:2.0.50727.42″ which I suspect didn’t change in 3.0 (looking at generated code above).
    It would especially be nice if nullable types would be supported in a new versions.

  8. [...] morning on using XLinq in XAML to facilitate databinding. I have to say, I’m still partial to generating CLR objects from XML, especially when I have full control over the schema and data source, but it’s nice to see [...]

  9. lymnsalasseNub October 6th, 2008 9:53 pm

    well done, brother

Leave a reply

Mexico