Saturday, September 19, 2009

XML to Class in .NET – XML Schema Definition Tool(XSD.exe)

Most of us faced the scenario that we need to deserialize the xml data got from a service or some other source to an object.So how can we do that?Lets have a look at that.
First of all i have an XML like,
<?xml version="1.0" encoding="UTF-8" ?>
<Orders>
<Customer Id="001">
<Name>Customer1</Name>
<Address>Address1</Address>
<EmailId>EmailId</EmailId>
<Items>
<Item Id="100" Name="Item1"/>
<Item Id="101" Name="Item2"/>
</Items>
</Customer>
<Customer Id="002">
<Name>Customer2</Name>
<Address>Address1</Address>
<EmailId>EmailId</EmailId>
<Items>
<Item Id="103" Name="Item3"/>
<Item Id="103" Name="Item4"/>
</Items>
</Customer>
</Orders>
So we need to generate a class from this XML.Here comes XML Schema Definition Tool or XSD.exe.So we are creating an XML Schema definition first from the above XML.
  • Go to Visual Studio>Visual Studio Tools>Visual Studio Command Prompt.
  • Navigate to the folder where we have the XML data or we can directly target the xml path.I am navigating to the folder having above xml and type the command xsd.exe Customer.xml and this'll generate a schema definition file Customer.xsd.

    XML Schema Definition looks like,
<?xml version="1.0" encoding="utf-8"?>
<xs:schema id="Orders" xmlns="" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xs:element name="Orders" msdata:IsDataSet="true" msdata:UseCurrentLocale="true">
<xs:complexType>
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:element name="Customer">
<xs:complexType>
<xs:sequence>
<xs:element name="Name" type="xs:string" minOccurs="0" msdata:Ordinal="0" />
<xs:element name="Address" type="xs:string" minOccurs="0" msdata:Ordinal="1" />
<xs:element name="EmailId" type="xs:string" minOccurs="0" msdata:Ordinal="2" />
<xs:element name="Items" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:element name="Item" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:attribute name="Id" type="xs:string" />
<xs:attribute name="Name" type="xs:string" />
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
<xs:attribute name="Id" type="xs:string" />
</xs:complexType>
</xs:element>
</xs:choice>
</xs:complexType>
</xs:element>
</xs:schema>
  • Now use command, xsd.exe Customer.xsd /c, for generate class from the schema definition file. It'll generate a class with default language as C#,customer.cs is generated in the folder and its having partial class Orders,
     /// <remarks/>
     [System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "2.0.50727.3038")]
[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 Orders {
Please note : you can see type OrdersCustomerItemsItem[][] for Items property and for its private variable.Change it as OrdersCustomerItemsItem[],Otherwise while Deserializing it'll show error.
  • By Using System.Xml.Serialization.XmlSerializer we can Deserialize the XML to Order object.

    private void PopulateData()
    {
        StreamReader stream = new StreamReader("Customer.xml");
        XmlSerializer serializer = new XmlSerializer(typeof(Orders));
        Orders orders = (Orders)serializer.Deserialize(stream);
    OrdersList.ItemsSource = orders.Items;
    }
  • Build and Run the application you can see the Customers displayed in the UI.

2 comments:

Joymon said...

Why can't we have linq?
http://joyfulwpf.blogspot.com/2008/12/xml-to-object-model-using-linq.html

Any performance problems?

AJ said...

Yeah we can do it like that.But i think using XMLSerializer is more straight approach.I don't know if there any performance difference.

Post a Comment