c# – Deserialize variational (typed) XML

Question:

Previously, I did not come across object serialization, especially serialization to XML and vice versa, but I had to – but I don’t know how to deal with objects in which there is a field of the Object class, in which there can be objects of several types.

XML example:

<Entities xmlns="http://site.ru/" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
  <Error i:nil="true"/>
  <Package xmlns:a="http://schemas.microsoft.com/2003/10/Serialization/Arrays">
    <a:anyType i:type="TypeA">
      <ID>123</ID>
      <Number>1001</Number>
    </a:anyType>
    <a:anyType i:type="TypeB">
      <ID>232</ID>
      <Type>1001</Type>
    </a:anyType>
    <a:anyType i:type="TypeC">
      <ID>943</ID>
      <Name>TheName</Name>
    </a:anyType>
  </Package>
</Entities>

XML example:

<Entities xmlns="http://site.ru/" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
  <Error>
    <Message>Error Message</Message>
  <Error/>
  <Package i:nil="true"/>
</Entities>

I assume that classes can be written like this (although I'm not sure about the record, because it doesn't work):

[XmlRootAttribute("Entities", Namespace = "http://site.org/", IsNullable = false)]
public class BoxPackages {
  [XmlArray(IsNullable = true)]
  public BoxError Error;
  [XmlArray(IsNullable = true)]
  public object[] Package;
}

public class BoxError {
    public String Message;
}

[XmlRootAttribute("TypeA")]
public class PackageTypeA {
  public Int32 ID;
  public Int64 Number;
}

[XmlRootAttribute("TypeB")]
public class PackageTypeB {
  public Int32 ID;
  public Byte Type;
}

[XmlRootAttribute("TypeC")]
public class PackageTypeC {
  public Int32 ID;
  public String Name;
}

It is clear that classes are not enough – some more configuration of the serializer is needed.
Does anyone know how to set up a serializer ( XmlAttributes out of the box) to deserialize the XML into an object of type BoxPackages ? Tell me please?

Answer:

The XmlSerializer class can only serialize known types. Because in the array object[] there can be any object of any type, in the constructor of this class, you must list all possible types of objects that are supposed to be used:

 Type [] extraTypes = new Type[3];
 extraTypes[0] = typeof(PackageTypeA);
 extraTypes[1] = typeof(PackageTypeB);
 extraTypes[2] = typeof(PackageTypeC);

 // Create the XmlSerializer instance.
 XmlSerializer mySerializer = new XmlSerializer(typeof(BoxPackages),extraTypes);

This example is based on the XmlSerializer constructor .

Scroll to Top