Home > Blockchain >  XML Deserialization Error ReadElementContentAs()
XML Deserialization Error ReadElementContentAs()

Time:05-05

I am working on deserializing the following XML document into a C# class:

<Station>
  <station_id>KMSP</station_id>
  <wmo_id>72658</wmo_id>
  <latitude>44.88</latitude>
  <longitude>-93.23</longitude>
  <elevation_m>255.0</elevation_m>
  <site>MINNEAPOLIS</site>
  <state>MN</state>
  <country>US</country>
  <site_type>
    <METAR />
    <TAF />
  </site_type>
</Station>

This is the class that it is being deserialized into:

    public class Station
    {
        [XmlElement(ElementName ="station_id")]
        public string StationId { get; set; }

        [XmlElement(ElementName = "wmo_id")]
        public string WmoId { get; set; }

        [XmlElement(ElementName ="latitude")]
        public double Latitude { get; set; }

        [XmlElement(ElementName = "longtitude")]
        public double Longtitude { get; set; }

        [XmlElement(ElementName="site")]
        public string Site { get; set; }

        [XmlElement(ElementName ="state")]
        public string State { get; set; }
        
        [XmlElement(ElementName ="country")]
        public string Country { get; set; }

        [XmlElement(ElementName = "site_type")]
        public string[] SiteType { get; set; }
    }

Everything seems to be deserializng correctly, except for the <site_type> tag. The contents of this tag will vary from Station to Station, but will always contain one or more items of a specific value - essentially from an enum. These tags are always self closing and do not ever contain attributes. They are strictly in the <METAR /> format. When I attempt to deserialize this XML, I get a ReadElementContentAs() error, and I am 99% sure it's that tag that is causing the issue. Would anyone happen to know where I went wrong on this, or have any advice on how to deserialize that kind of element?

Thank you!

CodePudding user response:

Taking your comment on this answer into account

For clarifcation, these type tags in the SiteType will never contain any data like the other tags. If the tag is present, it means that this weather station produces that type of report (METAR, TAF, SIGMENTS, etc)

That SiteType isn't an array of strings, but an array of types, with a different one per report type. All share the same base class.

public abstract class SiteType
{ }

public class Metar : SiteType
{ }

public class Taf : SiteType
{ }

That SiteType property then looks like below

[XmlArray(ElementName = "site_type")]
[XmlArrayItem(typeof(Metar), ElementName ="METAR")]
[XmlArrayItem(typeof(Taf), ElementName = "TAF")]
public SiteType[] SiteType { get; set; }

To check whether a certain report type is supported for a station, you check for the presence of the corresponding type within that SiteType array.

var hasMetar = p.SiteType.Any(o => o.GetType() == typeof(Metar));

CodePudding user response:

You can declare a property as follows:

[XmlAnyElement(Name = "site_type")]
public XmlElement SiteType { get; set; }

After deserialization, there will be a collection of nodes in the property.

foreach(XmlNode node in station.SiteType.ChildNodes)
    Console.WriteLine(node.Name);
  • Related