Парсинг сложной Xml в С#

273
22 сентября 2017, 17:10

Столкнулся с проблемой. У меня есть сложная xml.

<XML id="meter">
    <DATA>
        <SRL_NUM>Watershed0001150</SRL_NUM>
        <METER_ID>Watershed-0000001150</METER_ID>
        <MAC></MAC>
        <METER_ADDR>14 ff</METER_ADDR>
        <METER_TIME>06/03/2015 00:00:00</METER_TIME>
        <REC id="0">
            <TS>06/03/2015 00:00:00</TS>
            <C1>117</C1>
            <C2>10.5</C2>
        </REC>
        <REC id="60">
            <TS>06/03/2015 01:00:00</TS>
            <C1>100</C1>
            <C2>7</C2>
        </REC>
    </DATA>
</XML>

Надо это десериализовать в class. Я не могу понять, как это сделать, если у меня может быть от с1 до с10000000.

Answer 1

Один из вариантов - реализовать интерфейс IXmlSerializable, например:

[XmlRoot("XML")]
public class Xml
{
    [XmlAttribute("id")] public string Id { get; set; }
    [XmlElement("DATA")] public Data Data { get; set; }
}
public class Data
{
    [XmlElement("SRL_NUM")]    public string SrlNum { get; set; }
    [XmlElement("METER_ID")]   public string MeterId { get; set; }
    [XmlElement("MAC")]        public string Mac { get; set; }
    [XmlElement("METER_ADDR")] public string MeterAddr { get; set; }
    [XmlElement("METER_TIME")] public string MeterTime { get; set; }
    [XmlElement("REC")]        public List<Rec> Recs { get; } = new List<Rec>();
}
public class Rec : IXmlSerializable
{
    public int Id { get; set; }
    public string Ts { get; set; }
    public List<double> Cs { get; } = new List<double>();
    public XmlSchema GetSchema() => null;
    public void ReadXml(XmlReader reader)
    {
        Id = int.Parse(reader.GetAttribute("id"));
        reader.ReadStartElement();
        Ts = reader.ReadElementContentAsString("TS", "");
        while (reader.NodeType == XmlNodeType.Element)
            Cs.Add(reader.ReadElementContentAsDouble());
        reader.ReadEndElement();
    }
    public void WriteXml(XmlWriter writer)
    {
        writer.WriteStartAttribute("id");
        writer.WriteValue(Id);
        writer.WriteEndAttribute();
        writer.WriteStartElement("TS");
        writer.WriteValue(Ts);
        writer.WriteEndElement();
        for (int i = 0; i < Cs.Count; ++i)
        {
            writer.WriteStartElement("C" + (i + 1));
            writer.WriteValue(Cs[i]);
            writer.WriteEndElement();
        }
    }
}

Десериализация вполне стандартна:

string s = @"...";
var ser = new XmlSerializer(typeof(Xml));
var xml = (Xml)ser.Deserialize(new StringReader(s));
READ ALSO
Организация записи в файл

Организация записи в файл

Мой статический класс Logger пишет лог в текстовый файлФайл лога новый каждый день и на каждого пользователя

256
RdKafka Avro Consumer

RdKafka Avro Consumer

В клиенте RdKafka мне необходимо прочитать Avro сообщенияВ консоли я дописывал свойство:

178
asp.net mvc 5 C#

asp.net mvc 5 C#

в этом коде пишут ошибку

253