XSD to XML and XSD to C# XML Serializable Classes

Thanoshan MV
Level Up Coding
Published in
5 min readApr 28, 2024

--

Problem

  1. For the given XSDs, generate XML that gives us a basic idea on how the expected XML needs to look like which actually adheres to given XSDs
  2. For the given XSDs, create C# serializable classes that will generate XML which adheres to expected grammar definition

Let’s use NoteSchema and PurchaseOrderSchema for this problem.

<?xml version="1.0"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="https://www.w3schools.com/noteschema"
xmlns="https://www.w3schools.com/noteschema"
elementFormDefault="qualified">

<xs:element name="note">
<xs:complexType>
<xs:sequence>
<xs:element name="to" type="xs:string"/>
<xs:element name="from" type="xs:string"/>
<xs:element name="heading" type="xs:string"/>
<xs:element name="body" type="xs:string"/>
</xs:sequence>
</xs:complexType>
</xs:element>

</xs:schema>
<?xml version="1.0"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:tns="https://www.w3schools.com/purchaseorderschema"
targetNamespace="https://www.w3schools.com/purchaseorderschema"
elementFormDefault="qualified">

<xsd:element name="PurchaseOrder" type="tns:PurchaseOrderType"/>
<xsd:complexType name="PurchaseOrderType">
<xsd:sequence>
<xsd:element name="ShipTo" type="tns:USAddress" maxOccurs="2"/>
<xsd:element name="BillTo" type="tns:USAddress"/>
</xsd:sequence>
<xsd:attribute name="OrderDate" type="xsd:date"/>
</xsd:complexType>

<xsd:complexType name="USAddress">
<xsd:sequence>
<xsd:element name="name" type="xsd:string"/>
<xsd:element name="street" type="xsd:string"/>
<xsd:element name="city" type="xsd:string"/>
<xsd:element name="state" type="xsd:string"/>
<xsd:element name="zip" type="xsd:integer"/>
</xsd:sequence>
<xsd:attribute name="country" type="xsd:NMTOKEN" fixed="US"/>
</xsd:complexType>
</xsd:schema>

We have two schema definitions NoteSchema and PurchaseOrderSchema. Our problem is to generate XML that needs to contain both <note> element and <PurchaseOrder> element under the root element <Attachments>.

Solution — XSD to XML

As a first step, we need to create the Attachments schema by combing both schemas.

Make sure to have NoteSchema.xsd, PurchaseOrderSchema.xsd and Attachments.xsd in the same directory. If not, we need to add their relative path when generating the XML (in xs:import) and C# classes (in Command Prompt command).

<?xml version="1.0" encoding="utf-8"?>
<xs:schema targetNamespace="http://tempuri.org/XMLSchema.xsd"
elementFormDefault="qualified"
xmlns="http://tempuri.org/XMLSchema.xsd"

xmlns:xs="http://www.w3.org/2001/XMLSchema"

xmlns:no="https://www.w3schools.com/noteschema"
xmlns:po="https://www.w3schools.com/purchaseorderschema"

>

<!-- The targetNamespace declares a namespace for other xml and xsd documents to refer to this schema. -->

<!-- namespace = namespace to import. schemaLocation = schema that contains the namespeace to import -->
<xs:import schemaLocation="NoteSchema.xsd" namespace="https://www.w3schools.com/noteschema"/>

<xs:import schemaLocation="PurchaseOrderSchema.xsd" namespace="https://www.w3schools.com/purchaseorderschema"/>

<xs:element name="Attachments">
<xs:complexType>
<xs:sequence>
<xs:element ref="no:note"/>
<xs:element ref="po:PurchaseOrder"/>
</xs:sequence>
</xs:complexType>
</xs:element>

</xs:schema>

Here, take special care on xs:import, xmlns:no, xmlns:po and <xs:element ref="xx:yyy"/>.

Open the Attachments schema using Visual Studio.

Click on ‘Use the XML Schema Explorer to browse your entire schema as a tree’ option.

Click on ‘Generate Sample XML’.

This will create the sample XML that adheres to the given XSDs. Generated sample XML:

<?xml version="1.0" encoding="utf-8"?>
<Attachments xmlns="http://tempuri.org/XMLSchema.xsd">
<note xmlns="https://www.w3schools.com/noteschema">
<to>to1</to>
<from>from1</from>
<heading>heading1</heading>
<body>body1</body>
</note>
<PurchaseOrder OrderDate="1900-01-01" xmlns="https://www.w3schools.com/purchaseorderschema">
<ShipTo country="US">
<name>name1</name>
<street>street1</street>
<city>city1</city>
<state>state1</state>
<zip>1</zip>
</ShipTo>
<ShipTo country="US">
<name>name2</name>
<street>street2</street>
<city>city2</city>
<state>state2</state>
<zip>-79228162514264337593543950335</zip>
</ShipTo>
<BillTo country="US">
<name>name1</name>
<street>street1</street>
<city>city1</city>
<state>state1</state>
<zip>1</zip>
</BillTo>
</PurchaseOrder>
</Attachments>

In an advanced scenario where an element can have one child element amongst given three child elements and we want to focus on the second child element. In this case, this tool will generate the XML for the first child element by default. Since we need to focus on the second child element, we need to comment out the first child element and generate the XML.

Solution — XSD to C# XML Serializable Class

We can use XML Schema Definition Tool to create C# classes that will create XML which will adhere to the given schema definitions. This tool comes with .NET installation.

Find the tool location -> C:\Program Files (x86)\Microsoft SDKs\Windows\{version}\bin\NETFX {version} Tools\

Add it in environment variables.

Open Command Prompt. Run this script.

xsd /c Attachments.xsd NoteSchema.xsd PurchaseOrderSchema.xsd

Result:

//------------------------------------------------------------------------------
// <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>
//------------------------------------------------------------------------------

using System.Xml.Serialization;

//
// This source code was auto-generated by xsd, Version=4.8.3928.0.
//


/// <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://tempuri.org/XMLSchema.xsd")]
[System.Xml.Serialization.XmlRootAttribute(Namespace="http://tempuri.org/XMLSchema.xsd", IsNullable=false)]
public partial class Attachments {

private note noteField;

private PurchaseOrderType purchaseOrderField;

/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute(Namespace="https://www.w3schools.com/noteschema")]
public note note {
get {
return this.noteField;
}
set {
this.noteField = value;
}
}

/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute(Namespace="https://www.w3schools.com/purchaseorderschema")]
public PurchaseOrderType PurchaseOrder {
get {
return this.purchaseOrderField;
}
set {
this.purchaseOrderField = 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="https://www.w3schools.com/noteschema")]
[System.Xml.Serialization.XmlRootAttribute(Namespace="https://www.w3schools.com/noteschema", IsNullable=false)]
public partial class note {

private string toField;

private string fromField;

private string headingField;

private string bodyField;

/// <remarks/>
public string to {
get {
return this.toField;
}
set {
this.toField = value;
}
}

/// <remarks/>
public string from {
get {
return this.fromField;
}
set {
this.fromField = value;
}
}

/// <remarks/>
public string heading {
get {
return this.headingField;
}
set {
this.headingField = value;
}
}

/// <remarks/>
public string body {
get {
return this.bodyField;
}
set {
this.bodyField = value;
}
}
}

/// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.8.3928.0")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(Namespace="https://www.w3schools.com/purchaseorderschema")]
public partial class USAddress {

private string nameField;

private string streetField;

private string cityField;

private string stateField;

private string zipField;

private string countryField;

public USAddress() {
this.countryField = "US";
}

/// <remarks/>
public string name {
get {
return this.nameField;
}
set {
this.nameField = value;
}
}

/// <remarks/>
public string street {
get {
return this.streetField;
}
set {
this.streetField = value;
}
}

/// <remarks/>
public string city {
get {
return this.cityField;
}
set {
this.cityField = value;
}
}

/// <remarks/>
public string state {
get {
return this.stateField;
}
set {
this.stateField = value;
}
}

/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute(DataType="integer")]
public string zip {
get {
return this.zipField;
}
set {
this.zipField = value;
}
}

/// <remarks/>
[System.Xml.Serialization.XmlAttributeAttribute(DataType="NMTOKEN")]
public string country {
get {
return this.countryField;
}
set {
this.countryField = value;
}
}
}

/// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.8.3928.0")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(Namespace="https://www.w3schools.com/purchaseorderschema")]
[System.Xml.Serialization.XmlRootAttribute("PurchaseOrder", Namespace="https://www.w3schools.com/purchaseorderschema", IsNullable=false)]
public partial class PurchaseOrderType {

private USAddress[] shipToField;

private USAddress billToField;

private System.DateTime orderDateField;

private bool orderDateFieldSpecified;

/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute("ShipTo")]
public USAddress[] ShipTo {
get {
return this.shipToField;
}
set {
this.shipToField = value;
}
}

/// <remarks/>
public USAddress BillTo {
get {
return this.billToField;
}
set {
this.billToField = value;
}
}

/// <remarks/>
[System.Xml.Serialization.XmlAttributeAttribute(DataType="date")]
public System.DateTime OrderDate {
get {
return this.orderDateField;
}
set {
this.orderDateField = value;
}
}

/// <remarks/>
[System.Xml.Serialization.XmlIgnoreAttribute()]
public bool OrderDateSpecified {
get {
return this.orderDateFieldSpecified;
}
set {
this.orderDateFieldSpecified = value;
}
}
}

Using the above classes, the generated XML will adhere to the XSDs.

Benefits of using Visual Studio in generating the sample XML and XSD tool to generate C# classes is that we do not have to depend on external third parties, our data won’t be lost and continue our work officially with Microsoft.

--

--