The XsdToClasses tool is an add-in for Microsoft Visual Studio that automates code generation from XML Schema Definition files (XSD), and allows the programmer to control, tune and override code generation.
The tool is open source, and it is available here. It works with Visual Studio 2005, 2008, and 2010. Visual Studio Express Editions from 2005 through 2010 are also supported.
Only code generation in C# is supported. Code generation in VB is implicitly supported by the framework. Any customers requiring VB.NET code generation should contact us directly.
Patch
Certain versions of XsdToClasses may have trouble uninstalling. If you have this problem, it manifests itself when you attempt to uninstall, or attempt to install a newer version of the product. The process generates an error that indicates that the product has trouble uninstalling and does not complete.
A simple solution is to download the following file:
Extract the file named “XsdToClasses.dll” and place it in the program’s folder (usually C:Program Files/Blue Toque/XsdToClasses). Replace the existing assembly, and run the uninstall process from the control panel.
Prerequisites
- .NET Framework 3.5 (or higher)
- Visual Studio 2005, 2008, 2010 or Express Editions (not all are tested, let me know if you have trouble)
License
XsdToClasses is free, covered under the GNU GPL, as stated above, the source is available here. Feel free to download and modify it as you like.
Note that since the XsdToClasses tool is a code generator, the tool itself is GPL, but the code it generates is most definitely not; the output from the program can be under any license you like, much the same way that output from an image editor is not under license to the maker of the editor. Your generated code belongs to you.
I would of course appreciate feedback.
Change Log
- 01/09/11: Added an optional support library called BlueToque.Serializable to help with serialization/deserialization.
- 1.2.23 25/07/10:
- Added ImportFixer code modifier to take the place of the combination of “RemoveSpecifiedTypes” and “ModifyImports”; this code modifier will remove all classes that are generated from a given namespace, and modify the imports to import the library where the code is generated. This handles situations where you have a massive number of classes generated in an imported library, and changes to those classes (wither renaming or additions) causes a maintenance problem updating all the references. Documentation to follow.
- 1.2.22 18/06/10:
- Added RemoveXmlTypeAttribute Code Modifier to remove the XmlTypeAttribute in generated code for classes that implement IXmlSerializable. An error serializing these classes look like this:”Only XmlRoot attribute may be specified for the type <type>. Please use XmlSchemaProviderAttribute to specify schema type.”
- 1.2.21 12/05/10:
- added Support for Visual Studio 2010
- added a “date generated” string to generated files
- fixed uninstall problem (see Patch section above), generated patch assembly
- 1.1.21 26/10/09:
- minor bug fix
- 1.1.17 04/11/08:
- support for Visual Studio Express Editions
- added non serialized attribute to members that should not be serialized using a binary formatter. Using generated code with WCF endpoints using a binary encoding caused errors for fields that should not be serialized.
- 1.1.15 16/01/08:
- support for Visual Studio 2008
- 1.0.21.0:
- Set the following defaults:EnableDataBinding = true;GenerateComplexTypes = true;GenerateComplexTypesSpecified = true;GenerateDebuggableCode = true;
GenerateProperties = true;
GenerateSoapTypes = false;
- Set the following defaults:EnableDataBinding = true;GenerateComplexTypes = true;GenerateComplexTypesSpecified = true;GenerateDebuggableCode = true;
- 1.0.20.0:
- Bug fix: parameters for DataBinding, order and Properties being set but not honoured
- 1.0.19.0:
- Added parameters to config to enable and disable DataBinding, Order and Properties
- 1.0.17
- Added the ability to import types from foreign schemas without generating codeImport types from other assemblies using ModifyImports code modifierExclude types from being generated using the RemoveSpecifiedTypes code modifier
- 1.0.11: added generic collections
- 1.0.10: for added support for VS 2008
- 1.0.7: added import of externally referenced schemas (via the import schema directive)
- 1.0.5: bug fixes and refinements
- 1.0.3 03/04/06:
- added extensible support for code modifiers, created the XmlGridControl as an example project
- 1.0.2: added support from “tree” view of generated file and config file
- 1.0.1: added support for configuration files
- 1.0.0: initial edition automates the generation of code from an XSD Schema
Overview
XsdToClasses is a simple tool that attempts to generate code from an XML Schema. This process is called Code Generation and is useful for a number of reasons. For example, if you need to specify a schema for the generation of web services or to adhere to a standard, generating the code from such a schema simplifies coding and saves a step. The XML Data can be validated against the schema before deserialization. Generating schemas and the code to serialize and deserialize them allows the programmer to specify rich object models that also have easily verifiable XML storage models.
XsdtoClasses was written based on the framework tool xsd.exe. It uses the same .NET framework classes, and gives the added value that edits to the schema in Visual Studio result in generated code when the user saves the schema or when the project is built. In addition, this tool allows the user to tune the generated code to fit a number of scenarios:
- Control generation of DataBinding code
- including externally generated code files
- Control code generation by excluding types from being generated
- Extend code generation by writing custom CodeModifiers
- Handle the case where one schema references another schema for which you’ve already generated code
Usage
XsdToClasses installs as a Visual Studio Add-In.
- Select an XSD File. In the Properties dialog for the file there is an entry named “Custom Tool”.
- Enter ”XsdToClasses” in this entry.
If you wish the code to be generated in a specific namespace, in order to avoid collision of generated code type names with other names, you can either place the schema file in a subdirectory (in which case the schema’s namespace will take on the value of the directory), or specify the namespace using the “Custom Tool Namespace” field in the property grid.
Figure 1: XsdToClasses configuration
After entering the text, the Add-In will activate for the first time, and attempt to generate code from your schema. It will generate two files:
<schemaName>.Generated.cs: This file is the generated code. In the case that there was an error generating the code, the error and call stack information will be written as a comment in this file. See below for error information.
<schemaName>.Generated.xml: this file contains configurable parameters that affect the code generation. This is where parameters are set that change how or what code is generated.
Programming
All code generated using the XsdToClasses tool is generated as partial classes. This means each class is simple to extend by adding your own partial class.
Right-clicking on the project, and choose “Add Class”. Name the class the same name as the schema file. This will ensure that the class file is “nested” as a child of the schema file (see figure 1 – Configuration.cs). Edit the generated class, removing and adding classes to this file as partial classes are necessary.
Configuration
The configuration schema for XsdToClasses is included in the installation of the program. Basic features are as follows.
- EnableDataBinding: causes the code generator to create databinding compatible code. Each class derives from INotifyPropertyChanged, each property calls the PropertyChanged event.
- GenerateOrder: generates an order attribute that causes the XmlSerializer to enforce the order of elements in the serialized XML.
- GenerateProperties: causes properties to be created for each element and attribute. If this is set to false, the generator creates public fields. Setting this to false will have the side effect of disabling data binding (see above)
- CodeModifiers: code modifiers are the heart of the code generator. This configuration section specifies a set of code modifiers that are run in order after the basic code is generated. Each code modifier inspects the CodeDOM and can modify it in some way. Each code modifier can have it’s own configuration section nested in the code modifier description.
- SchemaImporterExtensions: this set of references can change how the schema is imported. For example, it can change how a custom type is mapped to a framework type, and can even map a ComplexType to an existing framework class.
Example
Schema imports
When one schema imports another, the code generator can not tell if code has already been generated for that import. In fact, since a schema can contain multiple namespaces internally, the code generator has no knowledge of the import, only that there are types specified which need to be generated.
How XsdToClasses solves this is by two code modifiers: RemoveSpecifiedTypes and ModifyImports.
RemoveSecifiedTypes has a configuration that allows the user to specify which types from the imrpoted schema to skip. The modifier does this by performing a text match on the class name of the generated type.
ModifyImports adds a “Using” statement to the code to reference the generated code in another namespace. If the code is generated in the same namespace then this will not be necessary.
Below is an example of this strategy.
<?xml version="1.0" encoding="utf-16"?> <Configuration xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://BlueToque.ca/XsdToClasses.Configuration"> <CodeModifiers> <CodeModifier Type="CodeGeneration.CodeModifiers.ConvertArraysToCollections" Assembly="CodeGeneration, Version=1.0.1.0, Culture=neutral, PublicKeyToken=46a422f5b652f20b" /> <CodeModifier Type="CodeGeneration.CodeModifiers.RemoveDebuggerAttribute" Assembly="CodeGeneration, Version=1.0.1.0, Culture=neutral, PublicKeyToken=46a422f5b652f20b" /> <CodeModifier Type="CodeGeneration.CodeModifiers.RemoveSpecifiedTypes" Assembly="CodeGeneration, Version=1.0.1.0, Culture=neutral, PublicKeyToken=46a422f5b652f20b" > <RemoveSpecifiedTypesOptions xmlns="http://BlueToque.ca/CodeGeneration/CodeModifiers/RemoveSpecifiedTypes.Options"> <Type Name="TagType" /> <Type Name="TagsType" /> <Type Name="TagTypeCollection" /> </RemoveSpecifiedTypesOptions> </CodeModifier> <CodeModifier Type="CodeGeneration.CodeModifiers.ModifyImports" Assembly="CodeGeneration, Version=1.0.1.0, Culture=neutral, PublicKeyToken=46a422f5b652f20b" > <ModifyImportsOptions xmlns="http://BlueToque.ca/CodeGeneration/CodeModifiers/ModifyImports.Options"> <AddImport Name="EmerGeo.MessageDataLib" /> </ModifyImportsOptions> </CodeModifier> </CodeModifiers> <SchemaImporterExtensions /> </Configuration>
Figure 2: a basic configuration file
The first part of the file defines the root element and the namespaces.
The CodeModifiers element defines the group of code modifiers. The four code modifiers present are the defaults that are found in the file when it is generated. The “RemoveSpecifiedTypesOptions” element causes the code generator to remove all instances of the given types from the CodeDOM after the basic code is generated. Each <Type> element specifies the name of a type to remove from the CodeDOM.
The ModifyImports element allows the user to specify “using” statements for the generated code. Each <AddImport> element specified the namespace to import. Note that this does not add the reference to that namespace to the project; the programmer must still perform that step.
Errors
Possible reasons for an error generating code
- Schema is not valid. If the schema is not valid the call stack will most likely have some sort of schema parsing error.
- Schema does not resolve to a valid representation in code.
There are many examples of schemas that cannot be represented as code. In general the XSD language can represent structures that do not have a singular code representation. The XsdToClasses code uses framework classes to attempt the resolve these into code structures, but in many cases this is not possible.