Roey Moyal
Roey Moyal

Reputation: 51

Deserialization an xml element that could be different types

I need to deserialize the flowing xml in c#

<Show>
   <status>Canceled</status>
</Show>

<Show>
    <status>2</status>
</Show>

my class is

[XmlRoot("Show")]`
public class Show
{
   [XmlElement(ElementName = "status")]
   public object status { get; set; }
}

and it works but i would like to deserialize it into an enum where in this example cancel is equal 2

public enum ShowStatus
{
   [XmlEnum("Canceled")]
   Canceled = 2
}

is there any way to do that without parse the public object status { get; set; } string value to enum

Upvotes: 1

Views: 966

Answers (2)

sa_ddam213
sa_ddam213

Reputation: 43636

If you want to Deserialize the Enum using the name or the integer you can decorate the Enum with XmlEnum attribute and supply the integer.

This will deserialise "Canceled" and "2" as your Enum.

Example:

[XmlRoot("Show")]
public class Show
{
    [XmlElement(ElementName = "status")]
    public ShowStatus status { get; set; }
}

public enum ShowStatus
{
    [XmlEnum("2")]
    Canceled = 2
}

Test xml:

<?xml version="1.0"?>
<ArrayOfShow xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <Show>
    <status>Canceled</status>
  </Show>
  <Show>
    <status>2</status>
  </Show>
</ArrayOfShow>

Upvotes: 1

Nevyn
Nevyn

Reputation: 2683

you cannot use object directly, XmlSerializer simply refuses to work with generics. Objects still have an underlying type, and when its de-serialzied, you have no idea what that type is. I made a workaround for it here but its not very pretty, or very useful.

You can custom implement IXmlSerializable, but that is a headache and a half.

I am assuming that the source of the problem is that you are taking this in as input from another source, and the field could be either integer or text, which you want to store as an enumerable. You are probably better of de-serializing it into a string, then simply parsing it later, afterwards. That would probably be the easiest way to do it. Everything else I can find is either about deserializing only the string values, or only the integer values, I have no idea if either of them can handle both forms of data, but it seems unlikely.

This Function will probably help you out a lot when it comes to that, it looks like it can handle the string or the numerical value, but I dont think XmlSerializer can use it. You would be better off with a string "dummy" that can save back to the Enum property using the Parse function. see this stackoverflow question for an example of the dummy property.

Example

Generally speaking it would look something like this:

[XmlRoot("Show")]`
public class Show
{
   [XmlIgnore()]
   public ShowStatus status { get; set; }

   [XmlElement(ElementName = "status")]
   public string StatusString
   {
       get { return status.ToString(); }
       set { status = Enum.Parse(ShowStatus, value); }
   }
}

Upvotes: 0

Related Questions