Turning XML into XmlSerializer CLR Types with xsd.exe
Here’s a common dilemma .NET developers encounter when working with XML: I have some XML that I want to represent in a strongly typed way, but I don’t have any XSDs to represent that XML. How do I turn that XML into CLR types that I can serialize?
Of course, I could go about manually creating XmlSerializer types that match the way the XML looks, but that’s usually unnecessary and always tedious. You could also look into the “Paste XML as Types” feature that’s part of the WCF REST starter kit as a Visual Studio add-in. But if you want to just get the job done from the command line without downloading or installing anything, this blog post is for you. We’ll make use of xsd.exe, which is part of the SDK for the .NET framework.
Suppose we’re starting out with the following snippet of XML:
<Library xmlns:i="https://www.w3.org/2001/XMLSchema-instance">
<Books>
<Book Rating="4">
<Author>
<FirstName>Kurt</FirstName>
<LastName>Vonnegut</LastName>
<MiddleName i:nil="true" />
</Author>
<Title>Welcome to the Monkey House</Title>
<Year>1968</Year>
</Book>
<Book Rating="5">
<Author>
<FirstName>Orson</FirstName>
<LastName>Card</LastName>
<MiddleName>Scott</MiddleName>
</Author>
<Title>Ender's Game</Title>
<Year>1985</Year>
</Book>
</Books>
<Name>Library Of Congress</Name>
</Library>
That we want to turn into XmlSerializer types. First, copy this bit of XML into a file named library.xml and run the following command:
xsd.exe library.xml
This should generate an XSD for the XML we started out with. If you open library.xsd, you’ll find the following schema:
<xs:element name="Library">
<xs:complexType>
<xs:sequence>
<xs:element name="Name" type="xs:string" minOccurs="0" />
<xs:element name="Books" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:element name="Book" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:element name="Title" type="xs:string" minOccurs="0" msdata:Ordinal="1" />
<xs:element name="Year" type="xs:string" minOccurs="0" msdata:Ordinal="2" />
<xs:element name="Author" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:element name="FirstName" type="xs:string" minOccurs="0" />
<xs:element name="LastName" type="xs:string" minOccurs="0" />
<xs:element name="MiddleName" type="xs:string" minOccurs="0" />
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
<xs:attribute name="Rating" type="xs:string" />
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
Which matches our original XML perfectly. Now, we just need to generate types based off the XSD, using xsd.exe again:
xsd.exe /classes library.xsd
This will generate a C# file called library.cs which contains the XmlSerializer types for your XML. And at this point, all you have to do is to compile the classes and to start deserializing instances of XML into your newly generated types or create instances of these types and serialize them out.
A couple notes:
· The names of the types won’t quite look natural. This happens because all of the types in the XSD are anonymous. I suggest renaming these to suit your needs.
· You should also get a “NewDataSet” class generated. This is an artifact of the way xsd.exe generates a schema for the XML. You can safely delete the class.