XSD.exe

Whenever two or more application inter-operate, there is a need of establishing a common set of rules for the format of the information that is exchanged.

Exchanged information can be represented, for example, as XML. The XML should have a well defined structure. In order to describe the structure of an XML document one can use XML Schema (more details here).

Now let us assume that we want to exchange an object called Message, that has two properties: Title (string) and Body (string):

XSD_MessageObject

In order to be able to represent Message objects as XML, we will define first the corresponding  XML Schema. I will use Notepad++ to create a file called Message.xsd that has the following content:

<?xml version="1.0"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:element name="Message">
    <xs:complexType>
      <xs:sequence>
        <xs:element name="title" type="xs:string"/>
        <xs:element name="body" type="xs:string"/>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
</xs:schema>

The Message.xsd should be known by all inter-operating applications, in order for them to understand and properly validate the XML representation of Message objects that will be exchanged.

In order to be able to generate XML representations of Message objects in C# , an easy approach would be the following:

  1. Use XML Schema Definition Tool (Xsd.exe) in order to generate C# class out of Message.xsd
  2. Use the generated C# Message class together with the XML Serialization in order to serialize to XML and deserialize from XML the Message objects

1. Generate the C# Message class

For this we will use Xsd.exe. The Xsd.exe tool is part of the .Net Framework and it should be available on your machine (if you have .Net Framework). More details are available here.

In order to generate the C# Message class follow the steps:

  • Open Visual Studio Command Prompt
  • Go to the location where Message.xsd has been saved
  • Run the following command:
xsd /classes /language:CS /namespace:XsdDemo Message.xsd

A Message.cs file should have been generated, with the following content:

//------------------------------------------------------------------------------
// <auto-generated>
//     This code was generated by a tool.
//     Runtime Version:4.0.30319.17929
//
//     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.0.30319.1.
// 
namespace XsdDemo {
    using System.Xml.Serialization;

    /// <remarks/>
    [System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.0.30319.1")]
    [System.SerializableAttribute()]
    [System.Diagnostics.DebuggerStepThroughAttribute()]
    [System.ComponentModel.DesignerCategoryAttribute("code")]
    [System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true)]
    [System.Xml.Serialization.XmlRootAttribute(Namespace="", IsNullable=false)]
    public partial class Message {

        private string titleField;

        private string bodyField;

        /// <remarks/>
        [System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
        public string title {
            get {
                return this.titleField;
            }
            set {
                this.titleField = value;
            }
        }

        /// <remarks/>
        [System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
        public string body {
            get {
                return this.bodyField;
            }
            set {
                this.bodyField = value;
            }
        }
    }
}

2. Use the C# Message class

In order to create the example I will use Visual Studio 2012 and .Net 4.5 Framework.

Let us create a Visual C# Console Application called XsdDemo:

XSD_ConsoleApplication

Next, we will add the Message.xsd and Message.cs existing items:

XSD_ConsoleApplication_Message

Next steps will be to:

  • instantiate the Message class
  • to serialize the instance to a string
  • to deserialize the string to a new Message instance

Below is the code that demonstrates all those steps:

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Serialization;

namespace XsdDemo
{
    class Program
    {
        static void Main(string[] args)
        {
            var message = new Message
            {
                title = "Title",
                body = "Body",
            };

            var stringFromMessage = MessageToString(message);
            Console.WriteLine(stringFromMessage);

            var messageFromString = StringToMessage(stringFromMessage);
            Debug.Assert(!ReferenceEquals(message, messageFromString));
            Debug.Assert(message.title == messageFromString.title);
            Debug.Assert(message.body == messageFromString.body);
        }

        private static string MessageToString(Message message)
        {
            string result = null;

            using (var memoryStream = new MemoryStream())
            {
                using (var streamWriter = new StreamWriter(memoryStream))
                {
                    var serializer = new XmlSerializer(typeof(Message));
                    serializer.Serialize(streamWriter, message);
                    streamWriter.Flush();
                    memoryStream.Position = 0;

                    using (var streamReader = new StreamReader(memoryStream))
                    {
                        result = streamReader.ReadToEnd();
                    }
                }
            }

            return result;
        }

        private static Message StringToMessage(string message)
        {
            using (var textReader = new StringReader(message))
            {
                var serializer = new XmlSerializer(typeof(Message));
                return serializer.Deserialize(textReader) as Message;
            }
        }
    }
}

As a conclusion I would say that Xsd.exe is a great tool for generating CLR classes out of XML Schema-s, it is able to handle complex schema-s, and it saves load of effort on serialization and deserialization.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s