DotNet XSD.exe generation tool

Introduction

Visual Studio comes with a multitude of utilities that can be used to generate code. As a Middleware I have used XSD.exe a lot to generate classes and Xsd schemas automatically.

How to use

Open a developer Command Prompt Type xsd, the application should show the list of possibilities proposed by the utility :

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
D:\Sources\Projects\xsd>xsd
Microsoft (R) Xml Schemas/DataTypes support utility
[Microsoft (R) .NET Framework, Version 4.8.3928.0]
Copyright (C) Microsoft Corporation. All rights reserved.

xsd.exe -
   Utility to generate schema or class files from given source.

xsd.exe <schema>.xsd /classes|dataset [/e:] [/l:] [/n:] [/o:] [/s] [/uri:]
xsd.exe <assembly>.dll|.exe [/outputdir:] [/type: [...]]
xsd.exe <instance>.xml [/outputdir:]
xsd.exe <schema>.xdr [/outputdir:]

    - OPTIONS -

/classes
   Generate classes for this schema. Short form is '/c'.

/dataset
   Generate sub-classed DataSet for this schema. Short form is '/d'.

/enableLinqDataSet
   Generate LINQ-enabled sub-classed Dataset for the schemas provided.  Short form is '/eld'.
...

Generate XSD from Xml file

To generate the Xsd schema for a specific xml file, go to the folder containing the sample file. Sample input sample.xml:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
<?xml version="1.0" encoding="utf-8" ?>
<root xmlns="http://mynamespace.com/sample">
  <row>
    <id>1</id>
    <parentid></parentid>
    <name>L1-A</name>
    <type>A</type>
  </row>
  <row>
    <id>11</id>
    <parentid>1</parentid>
    <name>L2-AA</name>
    <type>B</type>
  </row>
</root>

To Generate the schema in a subfolder named ‘output’ type the following command in the prompt :

1
2
3
4
D:\Sources\Projects\xsd>xsd sample.xml /nologo /o:output
Writing file 'output\sample.xsd'.

D:\Sources\Projects\xsd>

The schema generated looks like this :

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
<?xml version="1.0" encoding="utf-8"?>
<xs:schema id="root" targetNamespace="http://mynamespace.com/sample" xmlns:mstns="http://mynamespace.com/sample" xmlns="http://mynamespace.com/sample" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata" attributeFormDefault="qualified" elementFormDefault="qualified">
  <xs:element name="root" msdata:IsDataSet="true" msdata:Locale="en-US">
    <xs:complexType>
      <xs:choice minOccurs="0" maxOccurs="unbounded">
        <xs:element name="row">
          <xs:complexType>
            <xs:sequence>
              <xs:element name="id" type="xs:string" minOccurs="0" />
              <xs:element name="parentid" type="xs:string" minOccurs="0" />
              <xs:element name="name" type="xs:string" minOccurs="0" />
              <xs:element name="type" type="xs:string" minOccurs="0" />
            </xs:sequence>
          </xs:complexType>
        </xs:element>
      </xs:choice>
    </xs:complexType>
  </xs:element>
</xs:schema>

Generate Classes from XSD

To Generate the code from the schema in a subfolder named ‘output’ type the following command in the prompt :

1
2
3
4
D:\Sources\Projects\xsd>xsd output/sample.xsd /nologo /n:appns.xml /c /l:CS /o:output
Writing file 'output\sample.cs'.

D:\Sources\Projects\xsd>

/l is setting the language, there are several languages supported : CS, VB, CPP, JS, … the help of the tool will list all available options. /n will set the namespace used by within the class.

The tool is generating a class named sample.cs with the following code :

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
//------------------------------------------------------------------------------
// <auto-generated>
//     This code was generated by a tool.
//     Runtime Version:4.0.30319.42000
//
//     Changes to this file may cause incorrect behavior and will be lost if
//     the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------

// 
// This source code was auto-generated by xsd, Version=4.8.3928.0.
// 
namespace appns.xml {
   using System.Xml.Serialization;
   
   
   /// <remarks/>
   [System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.8.3928.0")]
   [System.SerializableAttribute()]
   [System.Diagnostics.DebuggerStepThroughAttribute()]
   [System.ComponentModel.DesignerCategoryAttribute("code")]
   [System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true, Namespace="http://mynamespace.com/sample")]
   [System.Xml.Serialization.XmlRootAttribute(Namespace="http://mynamespace.com/sample", IsNullable=false)]
   public partial class root {
       
       private rootRow[] itemsField;
       
       /// <remarks/>
       [System.Xml.Serialization.XmlElementAttribute("row")]
       public rootRow[] Items {
           get {
               return this.itemsField;
           }
           set {
               this.itemsField = value;
           }
       }
   }
   
   /// <remarks/>
   [System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.8.3928.0")]
   [System.SerializableAttribute()]
   [System.Diagnostics.DebuggerStepThroughAttribute()]
   [System.ComponentModel.DesignerCategoryAttribute("code")]
   [System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true, Namespace="http://mynamespace.com/sample")]
   public partial class rootRow {
       
       private string idField;
       
       private string parentidField;
       
       private string nameField;
       
       private string typeField;
       
       /// <remarks/>
       public string id {
           get {
               return this.idField;
           }
           set {
               this.idField = value;
           }
       }
       
       /// <remarks/>
       public string parentid {
           get {
               return this.parentidField;
           }
           set {
               this.parentidField = value;
           }
       }
       
       /// <remarks/>
       public string name {
           get {
               return this.nameField;
           }
           set {
               this.nameField = value;
           }
       }
       
       /// <remarks/>
       public string type {
           get {
               return this.typeField;
           }
           set {
               this.typeField = value;
           }
       }
   }
}

The code generated by the tool should never be altered. The main reason for this being the schema can change, and in that case we have to rerun the automation. There is a way to add code in a very simple way, to prevent the loss of custom code added in such case. See Extension Methods

When I am using Visual Studio, I use Pre-build event to generate automatically the code for the schemas I am using. And I dont need to worry about anything changing in my schemas. For specific code, I am creating new classes with Extension methods and I am never loosing the customization created.

Using multiple XSD files

To generate code from multiple xsd files, it is exactly the same command with the list of all schemas, first the referenced schemas, and last the main schema.

1
2
3
4
D:\Sources\Projects\xsd>xsd sub1.xsd sub2.xsd main.xsd /nologo /n:mynamespace /c /l:CS /o:output
Writing file 'output\main.cs'.

D:\Sources\Projects\xsd>

Conclusion

This xsd tool is really fast and easy to generate code from XML file or XSD schemas. It can also be used to automate the generation at compilation time with the pre-build events.

Reference

Microsoft Reference