I recommend writing classes to perform this transformation instead of using XML serialization, which requires a lot of extra work and ties your objects too closely to your data model.
On the other hand, sometimes you just have to deserialize collections from XML. To accomplish this, all you need to do is tell the XmlSerializer
which node to map to the collection.
By default, DataTable.WriteXml
creates a root element called <DocumentElement>
. For example, if you write from a DataTable
called "Name" that has "FirstName" and "LastName" columns, you'll get this:
<DocumentElement>
<Name>
<FirstName>Jon</FirstName>
<LastName>User</LastName>
</Name>
</DocumentElement>
The problem is that the XmlSerializer
doesn't know that "DocumentElement" should be deserialized to your collection class. There are two ways to tell it how.
By Convention
The XmlSerializer
knows that a root element named "ArrayOfMyClass" should map to collections of MyClass
.
Add your DataTable
to a DataSet
named "ArrayOfMyClass" to serialize it like this ...
<ArrayOfMyClass>
<MyClass>
// ... elements that map to properties of MyClass
</MyClass>
</ArrayOfMyClass>
.... which deserializes into a List<MyClass>
as desired.
By Hand
As an alternative, you can do it like this:
XmlRootAttribute root = new XmlRootAttribute("DocumentElement");
XmlSerializer serializer = new XmlSerializer(typeof(List<Name>), root);
Presuming everything else is ok (that is, your data row column names match your class' property names), this will deserialize as expected into your List<MyClass>
.
Edit: note that this approach has a rather severe problem (with a moderately cumbersome workaround) described in this SO question: XmlSerializer Performance Issue.