Tweaking the output of XSD.exe to use generics
Monday, August 20th, 2007A program I am working on heavily uses XML deserialization to build object models from XML files.
I didn’t have to write the deserialization code thanks to the excellent tool provided by Microsoft called XML Schema Definition Tool (Xsd.exe). This tool generates a bunch of C# classes that capture the data structure described in a given schema file (XSD files).
The generated code do have a few shortcomings though, like the use of arrays to handle multiple elements or the generation of FxCop unfriendly code. Jonathan ‘Peli’ de Halleux has already solved most of these problems in his XsdTidy, XSD mapping beautifier tool.
In my case, XsdTidy didn’t really work out of the box. My problems where slightly different:
- Use generics for multiple elements instead of array, e.g. List<sometype> instead of SomeType[].
- Use a tool runnable from the command line to integrate easily in my automated build system.
I could have hacked XsdTidy to solve these problems, but instead I went for the bad and the ugly: a quick and dirty regex script. I could have used perl, python or any other language that has a reasonably powerful regex engine, but I really have a soft spot for ruby. So here it goes, tweakXsd.rb, a quick and dirty, one-off job to tweak an xsd-generated class file to use generics.
Everytime I change my XSD schema files, I run a the MS-DOS script like the one below to regenerate C# classes, et voilà!
REM
REM This script generates Foo.cs from Foo.XSD
REM
SET XSD="C:\Program Files\Microsoft Visual Studio 8\SDK\v2.0\bin\xsd.EXE"
SET RUBY=C:\ruby\bin\ruby.exe
%XSD% /c /namespace:My.Namespace /order Foo.xsd
%RUBY% tweakXsd.rb < Foo.cs > Foo.cs.tmp
del Foo.cs
ren Foo.cs.tmp Foo.cs
As a bonus, the script tweaks elements defined as XmlTextAttribute to string properties instead of string[].
To produce a XmlTextAttribute compatible element, use the following schema declaration:
<xs:element name="elementWithText"> <xs:complexType mixed="true" /> </xs:element>
<french>
L’outil Xsd.exe proposé par Microsoft pour la création de classes de désérialisation XML à partir d’un fichier de schéma XML est réellement très utile. Le seul problème c’est que le code généré utilise des tableaux pour permettre l’accès aux collections d’éléments. Pour un projet je souhaitais pouvoir accéder à ces collections en utilisant des collections génériques de type List<T>. Après avoir écarté l’outil XsdTidy j’ai codé moi-même un script en mode “porcho” (cf. le Dictionnaire vosgien-français).
Le script tweakXsd.rb prend en entrée le résultat de “xsd.exe /c” et produit une version modifiée qui utilise les génériques et expose les attributs taggés XmlTextAttribute en tant que propriétés de type string au lieu de string[].
Le script MS-DOS cité plus haut montre un exemple d’automatisation du script.
</french>