54

So I have xml that looks like this:

<todo-list>
  <id type="integer">#{id}</id>
  <name>#{name}</name>
  <description>#{description}</description>
  <project-id type="integer">#{project_id}</project-id>
  <milestone-id type="integer">#{milestone_id}</milestone-id>
  <position type="integer">#{position}</position>

  <!-- if user can see private lists -->
  <private type="boolean">#{private}</private>

  <!-- if the account supports time tracking -->
  <tracked type="boolean">#{tracked}</tracked>

  <!-- if todo-items are included in the response -->
  <todo-items type="array">
    <todo-item>
      ...
    </todo-item>
    <todo-item>
      ...
    </todo-item>
    ...
  </todo-items>
</todo-list>

How would I go about using .NET's serialization library to deserialize this into C# objects?

Currently I'm using reflection and I map between the xml and my objects using the naming conventions.

heguchi
  • 27
  • 10
Justin Bozonier
  • 7,584
  • 9
  • 44
  • 46

7 Answers7

60

Create a class for each element that has a property for each element and a List or Array of objects (use the created one) for each child element. Then call System.Xml.Serialization.XmlSerializer.Deserialize on the string and cast the result as your object. Use the System.Xml.Serialization attributes to make adjustments, like to map the element to your ToDoList class, use the XmlElement("todo-list") attribute.

A shourtcut is to load your XML into Visual Studio, click the "Infer Schema" button and run "xsd.exe /c schema.xsd" to generate the classes. xsd.exe is in the tools folder. Then go through the generated code and make adjustments, such as changing shorts to ints where appropriate.

Dan Goldstein
  • 23,436
  • 10
  • 47
  • 51
  • 2
    In VS2010 it is called 'Create Schema' and may generate multiple xsd files (one per namespace). In that case, include those in the command, i.e. run "xsd.exe /c schema.xsd schema1.xsd " (etc). – Jeroen K Feb 02 '12 at 11:43
  • 6
    In VS 2012 and later, you also have "Paste XML as Classes" in the Edit menu. – Jonathan Allen Aug 31 '15 at 00:39
  • 4
    `Edit > Paste Special > Paste XML as Classes` Very nice, @JonathanAllen, exactly what I needed. – JMD Jan 08 '16 at 23:28
37

Boils down to using xsd.exe from tools in VS:

xsd.exe "%xsdFile%" /c /out:"%outDirectory%" /l:"%language%"

Then load it with reader and deserializer:

public GeneratedClassFromXSD GetObjectFromXML()
{
    var settings = new XmlReaderSettings();
    var obj = new GeneratedClassFromXSD();
    var reader = XmlReader.Create(urlToService, settings);
    var serializer = new System.Xml.Serialization.XmlSerializer(typeof(GeneratedClassFromXSD));
    obj = (GeneratedClassFromXSD)serializer.Deserialize(reader);

    reader.Close();
    return obj;
}
Community
  • 1
  • 1
Steve Horn
  • 8,818
  • 11
  • 45
  • 60
  • 1
    Hmmm, in the example I assume that the variable `urlToService` represents the serialized XML? And should that variable be an argument to `GetObjectFromXML()`? – DavidRR Dec 16 '13 at 20:08
  • For future visitors: `urlToService` can be the path to an xml file. Works like a charm. – Mafii Jun 22 '18 at 14:53
17

Deserialize any object, as long as the type T is marked Serializable:

function T Deserialize<T>(string serializedResults)
{
    var serializer = new XmlSerializer(typeof(T));
    using (var stringReader = new StringReader(serializedResults))
        return (T)serializer.Deserialize(stringReader);
}
Keith
  • 20,636
  • 11
  • 84
  • 125
4

Well, you'd have to have classes in your assembly that match, roughly, the XML (property called Private, a collection property called ToDo, etc).

The problem is that the XML has elements that are invalid for class names. So you'd have to implement IXmlSerializable in these classes to control how they are serialized to and from XML. You might be able to get away with using some of the xml serialization specific attributes as well, but that depends on your xml's schema.

That's a step above using reflection, but it might not be exactly what you're hoping for.

4

Checkout http://xsd2code.codeplex.com/

Xsd2Code is a CSharp or Visual Basic Business Entity class Generator from XSD schema.

Deepfreezed
  • 567
  • 2
  • 10
  • 18
  • @Deepfreezed: please give more detail. How would this solve the problem in this question. Maybe show a code example of using the tool. – John Saunders Apr 15 '10 at 23:48
  • First I generated the XSD schema for the XML using VS. Then I ran the code generation tool above. This generated a class/object that I can use to serialize the XML. This tool integrates with VS 2008/2010. It also has some nice features like generic collections. – Deepfreezed Apr 21 '10 at 21:07
3

There are a couple different options.

  • Visual Studio includes a command line program called xsd.exe. You use that program to create a schema document, and use the program again on the schema document to creates classes you can use with system.xml.serialization.xmlserializer
  • You might just be able to call Dataset.ReadXml() on it.
Joel Coehoorn
  • 399,467
  • 113
  • 570
  • 794
-1

i had the same questions few years back that how abt mapping xml to C# classes or creating C# classes which are mapped to our XMLs, jst like we do in entity Framework (we map tables to C# classes). I created a framework finally, which can create C# classes out of your XML and these classes can be used to read/write your xml. Have a look

Savaratkar
  • 1,974
  • 1
  • 24
  • 44