C#解析复杂XML LINQ

时间:2016-12-16 00:28:26

标签: c# xml linq parsing serialization

我一直试图解析以下XML文件并取得了一些成功。

<?xml version="1.0"?>
<Settings>
    <Tasks>
        <Task ID="1" Name="task_1" Active="1" NextEID="25" AR="0" CacheNames="random">
            <Schedules>
                <Schedule OnlyUntilFirstSuccess="0" FailIfNoSuccessInSched="0" RunEvenIfNotif="0">
                    <Days>
                        <DayOfWeek>Monday</DayOfWeek>
                        <DayOfWeek>Tuesday</DayOfWeek>
                        <DayOfWeek>Wednesday</DayOfWeek>
                        <DayOfWeek>Thursday</DayOfWeek>
                        <DayOfWeek>Friday</DayOfWeek>
                        <DayOfWeek>Saturday</DayOfWeek>
                        <DayOfWeek>Sunday</DayOfWeek>
                    </Days>
                    <Frequency>
                        <Interval StartTime="09:45" EndTime="09:45" EveryMinutes="0"></Interval>
                    </Frequency>
                </Schedule>
            </Schedules>
        </Task>
        <Task ID="2" Name="task_2" Active="1" NextEID="25" AR="0" CacheNames="random">
            <Schedules>
                <Schedule OnlyUntilFirstSuccess="0" FailIfNoSuccessInSched="0" RunEvenIfNotif="0">
                    <Days>
                        <DayOfWeek>Monday</DayOfWeek>
                        <DayOfWeek>Tuesday</DayOfWeek>
                        <DayOfWeek>Wednesday</DayOfWeek>
                        <DayOfWeek>Thursday</DayOfWeek>
                        <DayOfWeek>Friday</DayOfWeek>
                        <DayOfWeek>Saturday</DayOfWeek>
                        <DayOfWeek>Sunday</DayOfWeek>
                    </Days>
                    <Frequency>
                        <Interval StartTime="12:45" EndTime="09:45" EveryMinutes="0"></Interval>
                    </Frequency>
                </Schedule>
            </Schedules>
        </Task>
    </Tasks>
</Settings>

在线使用多个教程我将以下C#代码拼凑在一起:

public static void ParseXml()
        {
            string strFile = "File.xml";

            XDocument xdoc = XDocument.Load(strFile);

            var tasks = from s in xdoc.Descendants("Tasks")
                        select new
                        {
                            taskID = s.Element("Task").Attribute("ID").Value,
                            taskName = s.Element("Task").Attribute("Name").Value,
                            taskActive = s.Element("Task").Attribute("Active").Value,
                            taskSchedule = s.Element("Task").Element("Schedules").Element("Schedule").Element("Days")
                        };

            foreach (var t in tasks)
            {
                Console.WriteLine("Task Id :: {0}", t.taskID);
                Console.WriteLine("Task Name :: {0}", t.taskName);
                Console.WriteLine("Task Status :: {0}", t.taskActive);
                Console.WriteLine("Task Schedule :: {0}", t.taskSchedule);
            }

            Console.ReadKey();
        }

我的目标是解析每项任务,任务ID,名称,天数,频率。我希望最终能够使用这些值来绘制散点图图表上的TaskID和StartTime。我尝试创建以下类,认为它可以帮助我处理它的文件,但我不知道如何将它们组合在一起。

        public class Task
        {
            public static int taskId { get; set; }
            public static string taskName { get; set; }
        }

        public class Schedule
        {
            public enum DayOfWeek
            {
                Monday,
                Tuesday,
                Wednsday,
                Thursday,
                Friday,
                Saturday,
                Sunday
            }
        }

        public class Frequency
        {
            public static DateTime startTime { get; set; }
            public static DateTime endTime { get; set; }
            public static int everyMins { get; set; }
        }

任何帮助/指示将不胜感激。如果您有解决方案,请不要发布解决方案。请解释一下,以便我可以从中学习并在将来为这个社区做出贡献。

谢谢! 加布

1 个答案:

答案 0 :(得分:0)

首先,您需要根据源XML构建类。这是一个Settings类,其中包含Tasks等等。像这样的东西。我当然没有提供所有的XML属性。但你应该得到要点。您需要[XMLAttribute]属性来装饰代表XML属性的属性。此外,所有属性名称都区分大小写。所以一定要匹配(ID而不是Id)。但是有很多方法可以使用属性:

    public class Settings
    {
        public List<Task> Tasks { get; set; }
    }

    public class Task
    {
        [XmlAttribute]
        public int ID { get; set; }

        [XmlAttribute]
        public string Name { get; set; }
        public List<Schedule> Schedules { get; set; }

    }

    public class Schedule
    {
        [XmlAttribute]
        public string OnlyUntilFirstSuccess { get; set; }
        public List<DayOfWeek> Days { get; set; }
        public Frequency Frequency { get; set; }

    }
    public class Frequency
    {
        public Interval Interval { get; set; }
    }

    public class Interval
    {
        [XmlAttribute]
        public string StartTime { get; set; }
        [XmlAttribute]
        public string EndTime { get; set; }
        [XmlAttribute]
        public int EveryMins { get; set; }
    }

然后,您可以使用XmlSerializer将XML序列化到您的班级。因此,您的ParseXml()方法应如下所示:

    public static void ParseXml()
    {
        string fileName = "File.xml";
        XDocument xdoc = XDocument.Load(fileName);
        using (TextReader reader = new StringReader(xdoc.ToString()))
        {
            try
            {
                var settings = (Settings)new XmlSerializer(typeof(Settings)).Deserialize(reader);
            }
            catch (Exception ex)
            {
                // Handle exceptions as you see fit
            }
        }
    }

其他注意事项:不要将变量命名为strxxxxx来表示它们是字符串,标准约定是公共变量名称以大写字母开头。 此外,您还需要以下内容:

using System;
using System.Collections.Generic;
using System.IO;
using System.Xml.Linq;
using System.Xml.Serialization;