简体   繁体   English

C#解析复杂的XML LINQ

[英]C# Parsing Complex XML LINQ

I have been trying to parse the following XML file with some success. 我一直在尝试成功解析以下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>

Using several tutorials online I have pieced together the following C# code : 通过在线使用多篇教程,我将以下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();
        }

My goals is to parse out each task, task ID, Name, Days, Frequency. 我的目标是解析每个任务,任务ID,名称,天数,频率。 I'd like to ultimately be able to use these values to chart the TaskID and StartTime on a scatter plot graph. 我希望最终能够使用这些值在散点图上绘制TaskID和StartTime的图表。 I tried creating the following classes thinking it might help me deal with it the file but I don't know how to tie it all together. 我尝试创建以下类,以为它可以帮助我处理文件,但我不知道如何将它们捆绑在一起。

        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; }
        }

Any help / direction would be appreciated. 任何帮助/方向将不胜感激。 Please just don't post the solution if you have one. 如果您有解决方案,请不要发布解决方案。 Please explain it so that I can learn from it and contribute to this community in the future. 请解释一下,以便我可以从中学习并在将来为这个社区做出贡献。

Thanks! 谢谢! Gabe 加布

Firstly, you'll need to structure your classes as per the source XML. 首先,您需要根据源XML构建类。 So a Settings class within which you have Tasks and so on. 因此,其中包含TasksSettings类。 Something like this. 这样的事情。 I haven't put in all the XML attributes of course. 当然,我并没有输入所有XML属性。 But you should get the gist. 但是,你应该得到要点。 You need the [XMLAttribute] attribute decorating your properties representing XML attributes. 您需要[XMLAttribute]属性来修饰代表XML属性的属性。 Also all the property names are case sensitive. 同样,所有属性名称都区分大小写。 So be sure they match (ID instead of Id). 因此,请确保它们匹配(ID而不是ID)。 There are ways around this using attributes though: 尽管有一些方法可以使用属性:

    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; }
    }

Then you can use an XmlSerializer to serialize the XML to your class. 然后,您可以使用XmlSerializer将XML序列化到您的类。 So your ParseXml() method should look something like this: 因此,您的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
            }
        }
    }

Other things to note: don't name variable strxxxxx to denote they are strings and standard convention is that public variable names start with capital letters. 其他注意事项:不要使用变量strxxxxx来表示它们是字符串,并且标准约定是公用变量名称以大写字母开头。 Also, you'll need the following: 另外,您将需要以下内容:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM