Чтение xml файла в приложении winform(C#)

186
31 декабря 2018, 13:30

Необходимо считать данные с xml файла.

<?xml version="1.0" encoding="utf-8"?>
<Diagram xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <Elements>
    <HeatingPanel Id="0" Name="ЩУЭ-1" Location="400;-150" Temperature="4" IsInAlarm="true" IsEntryAutomateOn="0" IsNetworkOn="0" IsPowerOn="0" IsOnUps="-1" />
    <HeatingLine Id="1" Name="JB1" Location="238,8099;-39,37645" Temperature="-8" ParentId="0" State="Warning" />
    <Sensor Id="2" Name="TD1" Location="191,2572;-23,92546" Temperature="22" >

Разобрав файл, я создал три класса Heating_Panel, Heating_Line, Sensor. Далее на Form1 я пишу метод считывания элементов файла. Вот тут у меня возникла проблема. Мне надо считывать файл и одновременно проверять значение имени и исходя из этого парсить. Допустим если name="ЩУЭ" то парсить соответственно Heating_Panel. Если name = "JB" то парсить Heatinп_Line.Не понимаю как это сделать.

private void LoadHeating_Panel()
    {
        XmlDocument doc = new XmlDocument();
        doc.Load("Test.xml");
        foreach (XmlNode node in doc.DocumentElement.FirstChild.ChildNodes)
        {
            int id = int.Parse(node["Id"].InnerText);
            string name = node.Attributes[1].Value;
            double location = double.Parse(node["Location"].InnerText);
            double temperature = double.Parse(node["Temperature"].InnerText);
            bool isonalarm = bool.Parse(node["IsOnAlarm"].InnerText);
            int isentryautomateon = int.Parse(node["IsEntryAutomateOn"].InnerText);
            int isnetwork = int.Parse(node["IsNetwork"].InnerText);
            int poweron = int.Parse(node["PowerOn"].InnerText);
            int isonups = int.Parse(node["IsOnUps"].InnerText);
        }
    }

Сделал парсинг в ручную и только для одного класса.А мне надо сделать парсинг всего файла целиком.Не хватает знаний.

Answer 1

Содержимое файла xml как в вопросе, только нужно добавить закрывающие теги.

Собственно класс для парсинга такого файла

public class XmlService
{
    public static Elements GetElements(string pathToFile)
    {
        if (String.IsNullOrEmpty(pathToFile)) return null;
        if (!File.Exists(pathToFile)) return null;
        Elements result = ReadAndGetElements(pathToFile);
        return result;
    }
    private static Elements ReadAndGetElements(string pathToFile)
    {
        Elements result = new Elements();
        try
        {
            var doc = XDocument.Load(pathToFile);
            var hLines = doc.Descendants("Elements").Elements("HeatingLine").ToList();
            var hPanels = doc.Descendants("Elements").Elements("HeatingPanel").ToList();
            var sensors = doc.Descendants("Elements").Elements("Sensor").ToList();
            ParseHeatingLines(result, hLines);
            ParseHeatingPanels(result, hPanels);
            ParseSensors(result, sensors);
        }
        catch (Exception ex)
        {
            Debug.WriteLine($"Ошибка чтения и парсинга файла: {ex.Message}");
        }
        return result;
    }
    private static void ParseHeatingLines(Elements result, List<XElement> hLines)
    {
        foreach (var lineXml in hLines)
        {
            int id;
            string name;
            double[] locations;
            double temperature;
            ParseBaseProperties(lineXml, out id, out name, out locations, out temperature);
            int parentId = Int32.Parse(lineXml.Attribute("ParentId").Value);
            string state = lineXml.Attribute("State").Value;
            var line = new HeatingLine
            {
                Id = id,
                Name = name,
                Locations = locations,
                Temperature = temperature,
                ParentId = parentId,
                State = state
            };
            result.HeatingLines.Add(line);
        }
    }
    private static void ParseHeatingPanels(Elements result, List<XElement> hPanels)
    {
        foreach (var panelXml in hPanels)
        {
            int id;
            string name;
            double[] locations;
            double temperature;
            ParseBaseProperties(panelXml, out id, out name, out locations, out temperature);
            bool isOnAlarm = Boolean.Parse(panelXml.Attribute("IsInAlarm").Value);
            int isEntryAutomateOn = Int32.Parse(panelXml.Attribute("IsEntryAutomateOn").Value);
            int isNetworkOn = Int32.Parse(panelXml.Attribute("IsNetworkOn").Value);
            int isPowerOn = Int32.Parse(panelXml.Attribute("IsPowerOn").Value);
            int isOnUps = Int32.Parse(panelXml.Attribute("IsOnUps").Value);
            var panel = new HeatingPanel
            {
                Id = id,
                Name = name,
                Locations = locations,
                Temperature = temperature,
                IsOnAlarm = isOnAlarm,
                IsEntryAutomateOn = isEntryAutomateOn,
                IsNetworkOn = isNetworkOn,
                IsPowerOn = isPowerOn,
                IsOnUps = isOnUps
            };
            result.HeatingPanels.Add(panel);
        }
    }
    private static void ParseSensors(Elements result, List<XElement> sensors)
    {
        foreach (var sensorXml in sensors)
        {
            int id;
            string name;
            double[] locations;
            double temperature;
            ParseBaseProperties(sensorXml, out id, out name, out locations, out temperature);
            var sensor = new Sensor
            {
                Id = id,
                Name = name,
                Locations = locations,
                Temperature = temperature
            };
            result.Sensors.Add(sensor);
        }
    }
    private static void ParseBaseProperties(XElement sensorXml, out int id, out string name, out double[] locations, out double temperature)
    {
        id = Int32.Parse(sensorXml.Attribute("Id").Value);
        name = sensorXml.Attribute("Name").Value;
        string[] strLocs = sensorXml.Attribute("Location")
                                    .Value
                                    .Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries);
        locations = new double[strLocs.Length];
        for (int i = 0; i < locations.Length; i++)
        {
            locations[i] = double.Parse(strLocs[i]);
        }
        temperature = double.Parse(sensorXml.Attribute("Temperature").Value);
    }
}

использование класса

_elements = XmlService.GetElements(_openFileDialog.FileName);

вот классы для сбора информации

public abstract class BaseElement
{
    public int Id { get; set; }
    public string Name { get; set; }
    public double[] Locations { get; set; }
    public double Temperature { get; set; }
}
public class HeatingLine : BaseElement
{
    public int ParentId { get; set; }
    public string State { get; set; }
}
public class HeatingPanel : BaseElement
{
    public bool IsOnAlarm { get; set; }
    public int IsEntryAutomateOn { get; set; }
    public int IsNetworkOn { get; set; }
    public int IsPowerOn { get; set; }
    public int IsOnUps { get; set; }
}
public class Sensor : BaseElement
{
}
public class Elements
{
    public List<HeatingLine> HeatingLines { get; set; } = new List<HeatingLine>();
    public List<HeatingPanel> HeatingPanels { get; set; } = new List<HeatingPanel>();
    public List<Sensor> Sensors { get; set; } = new List<Sensor>();
}

Пример можно качнуть здесь

READ ALSO
Не отправляется файл ajax запросом

Не отправляется файл ajax запросом

Очень странная ситуацияКогда запускаю проект в студии, выбираю файл в форме он отправляется и возвращает нужные мне данные

202
xamarin.forms mscorlib конфликт зависимости

xamarin.forms mscorlib конфликт зависимости

Собрал проект, всё хорошоЗапускаю андроид приложение и выводится такая ошибка

298
Сохранение имени картинки в базе данных

Сохранение имени картинки в базе данных

yii2-advanced, сохраняю и записываю картинку к записи в бд

269
Не могу вывести пагинацию WordPress

Не могу вывести пагинацию WordPress

Я создал страницу новостей, как обычную страницу с помощью шаблона

178